Archivio tag: Configuration

Tomcat 7, jndi datasource ed eclipse

Piccola guida per la risoluzione di un banale task ma che spesso crea problemi, e cioè la definizione di un datasource jdbc su Tomcat .
Nel caso specifico utilizzo un datasource con driver SqlServer di Microsoft.
La libreria Microsoft contenente il driver jdbc (nel mio caso la sqljdbc4.jar), deve essere messa nella cartella lib del server tomcat.
Va poi configurata la risorsa jndi nel file server.xml nella cartella conf di tomcat, aggiungendo ad esempio questo :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!--?xml version="1.0" encoding="UTF-8"?-->
<!--contenuto vario del nostro file server,trovare l'elemento globalnamingresources e aggiungere la nostra resource-->
<GlobalNamingResources>
<Resource name="jdbc/testdb" auth="Container" type="javax.sql.DataSource"
        username="kiraya"
        password="kiraya"
        factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"

        driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
        url="jdbc:sqlserver://xx.xx.xx.xx:1433;DatabaseName=MYDB"
        maxActive="50"
        maxIdle="10"
        maxWait="15000"
        removeAbandoned="true"
       removeAbandonedTimeout="30"
       logAbandoned="true"
        validationQuery="select 1" />

</GlobalNamingResources>

Fatto questo, per poter rendere visibile al contesto web della nostra webapplication il driver, senza essere costretti a registrarlo manualmente tramite il DriverManager, mettiamo un resource-link o copiamo direttamente l’xml della definizione resource sopra inserita, nel file context.xml della cartella conf di tomcat, od in un file context.xml nella cartella META-INF della webapplication.
Dovendo rilasciare l’applicazione su diversi application server, preferisco non portare specifici files di configurazione nell’applicazione(ove possibile) e quindi lascio il file context.xml nella cartella config del server tomcat.

Contenuto del context.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0" encoding="UTF-8"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
--><!-- The contents of this file will be loaded for each web application --><Context>

    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <Resource name="jdbc/testdb" auth="Container" type="javax.sql.DataSource"
        username="kiraya"
        password="kiraya"
        factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"

        driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
        url="jdbc:sqlserver://xx.xx.xx.xx:1433;DatabaseName=MYDB"
        maxActive="50"
        maxIdle="10"
        maxWait="15000"
        removeAbandoned="true"
       removeAbandonedTimeout="30"
       logAbandoned="true"
        validationQuery="select 1" />    -->

    <!-- Uncomment this to enable Comet connection tacking (provides events
        on session expiration as well as webapp lifecycle) -->
    <!--
   <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
   -->

</Context>

Fatto questo, possiamo utilizzare una lookup jndi nella maniera classica per ottenere una connessione db.

1
2
3
javax.naming.InitialContext context = new javax.naming.InitialContext();
DataSource ds = (DataSource)context.lookup("java:/comp/env/jdbc/testdb");
Connection conn = ds.getConnection();

Se tomcat è configurato come server Runtime dentro eclipse, e quindi lo start e stop viene fatto da li, allora il file context da modificare non è quello della cartella conf del server ma quella della versione gestita da Eclipse, generalmente contenuta nel workspace, nella cartella Server..

Java AspectJ e Spring Framework: Aspect Oriented Programming in poche mosse

Il caso: vogliamo realizzare una funzione monitoraggio sulle nostre classi senza dover modificare tutta la nostra applicazione. Un sistema molto veloce è quello di utilizzare Aop.

Andiamo quindi a realizzare un aspetto che esegua rilevazioni di tempi (ovviamente e’ solo un esempio , ci sono centinaia di sistemi per farlo) sull’esecuzione di un metodo in particolare di alcune classi che andremo ad intercettare.

Realizzeremo quindi un aspect che scatterà durante l’esecuzione (around) di un particolare metodo di una particolare famiglia di classi che definiremo direttamente su spring. Questo ci permetterà di rilevare il tempo alla chiamata, eseguire il metodo, e rilevare il tempo a fine chiamata o a eccezione tornata.

Ovviamente ci sono molti modi per fare questo (utilizzando le annotations ad esempio).

Questo esempio e’ fatto completamente sfruttando il lato configurazione, con nessun intervento specifico sul nostro sorgente iniziale(apparte la definizione del nostro advice), quindi adatto ad essere introdotto in un progetto gia in fase avanzata di sviluppo.

Innanzitutto definiamo la classe che rappresenta il nostro advice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package it.mypackage.aspect;

import org.aspectj.lang.ProceedingJoinPoint;

public class AspectProfiler {

public Object profile(ProceedingJoinPoint call,MiContesto context) throws Throwable {

long start = System.nanoTime();

//proseguo con l'invocazione del metodo intercettato

try {

return call.proceed();

}catch(Exception ex){

ex.printStackTrace();

throw new Exception(ex);

}finally{

long stop = System.nanoTime();

System.out.println("Tempo esecuzione:" + ((stop-start)/1000000) + " ms");

}

}

}

Utilizziamo Spring 3 , quindi come prima cosa portiamo dentro il nostro file di configurazione i namespace corretti:

importante il namespace AOP.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

http://www.springframework.org/schema/context

<a href="http://www.springframework.org/schema/context/spring-context-3.0.xsd">
http://www.springframework.org/schema/context/spring-context-3.0.xsd</a>">

Ora sempre nel file di configurazione abilitiamo il component-scan del package interessato ad essere intercettato e proxato:

1
2
3
<context:annotation-config/>

<context:component-scan base-package="it.mypackage" />

Ora definiamo il nostro advice, l’aspetto profiler:

1
<bean id="profiler" class="it.mypackage.aspect.AspectProfiler" />

Ovviamente per poter essere intercettati in maniera corretta, gli oggetti devono essere creati tramite la bean factory di

Spring (in quanto devono essere creati come proxy) quindi definiti al suo interno:

1
<bean id="miaClasse" class="it.mypackage.mieclassi.miaclasseimpl/>

Ora definiamo tutta la parte aop su spring:

  • definiamo un aspetto e come riferimento gli diamo l’id del bean che mappa il nostro advice definito in precedenza;
  • definiamo un pointcut, dandogli un id arbitrario, e un’espressione . Questo è a tutti gli effetti il joint-point che una volta raggiunto (al verificarsi dell’espressione) nell’esecuzione del nostro codice, farà scattare ed eseguire l’advice;
  • definiamo la tipologia dell’advice come around(intorno all’esecuzione del metodo) e indichiamo il metodo dell’advice che verrà eseguito, ad esempio il metodo “profile” nell’espressione andiamo ad indicare che il joint-point da intercettare e’ quando viene eseguito il metodo execute di una classe che estenda la classe MiaClasseBase e che abbia come argomento un parametro chiamato context.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<aop:config >

<aop:aspect ref="profiler">

<aop:pointcut id="theExecutionOfExcecMethod"

expression="execution(* it.mypackage.mieclassi.MiaClasseBase+.execute(*)) and args

(context)"/>


<aop:around pointcut-ref="theExecutionOfExcecMethod" method="profile"/>

</<aop:aspect >

</aop:config >

Utilizzando un bean con id miaClasse ottenuto dal context di spring, vedremo eseguire il codice del nostro advice..

La documentazione di AspectJ e di Spring Framework e’ in continua evoluzione, quindi vi consiglio di controllarla spesso.