<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Information Centre &#187; JEE</title>
	<atom:link href="http://my.center-of.info/category/jee/feed/" rel="self" type="application/rss+xml" />
	<link>http://my.center-of.info</link>
	<description>“Wenn etwas schon da war, wie kann man es dann patentieren?” D.E.Knuth, 2002</description>
	<lastBuildDate>Sat, 22 Oct 2011 11:09:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>CDI in JavaSE</title>
		<link>http://my.center-of.info/2011/10/22/cdi-in-javase/</link>
		<comments>http://my.center-of.info/2011/10/22/cdi-in-javase/#comments</comments>
		<pubDate>Sat, 22 Oct 2011 11:06:03 +0000</pubDate>
		<dc:creator>Haf</dc:creator>
				<category><![CDATA[DevEnv]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[Notes]]></category>
		<category><![CDATA[cdi]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://my.center-of.info/?p=198</guid>
		<description><![CDATA[CDI – Contexts and Dependency Injection for the Java(tm) EE platform [1] &#8211; ist nicht neu und man findet im Netz auch genug gute Einführungen (z.B. [2] und natürlich immer auch bei [3], [4] etc). Möchte man jedoch CDI außerhalb eines Container (AppServer) verwenden, sprich in einer Java SE Umgebung, sucht man schon etwas länger. [...]]]></description>
			<content:encoded><![CDATA[<p>CDI – Contexts and Dependency Injection for the Java(tm) EE platform [1] &#8211; ist nicht neu und man findet im Netz auch genug gute Einführungen (z.B. [2] und natürlich immer auch bei [3], [4] etc). Möchte man jedoch CDI außerhalb eines Container (AppServer) verwenden, sprich in einer Java SE Umgebung, sucht man schon etwas länger.<br />
<span id="more-198"></span><br />
Bei CDI gibt es u.a. folgende Implementierungen: Weld [5] und OpenWebBeans [6].<br />
Bei der Referenzimplementierung Weld ist die Dokumentation vorbildlich und es gibt auch ein Kapitel [7] welches den Einsatz in einer Java SE Umgebung beschreibt. Solch ein Kapitel sucht man bei OpenWebBeans leider vergebens – das Kapitel an sich existiert schon, leider ohne Inhalt.<br />
Zum Glück findet man im SVN jedoch ein SE-Bespiel [8].<br />
Für Version 1.1.2 ersetzt man folgende Zeil:</p>
<pre class="brush: java">lifecycle = WebBeansContext.getInstance().getService(ContainerLifecycle.class);</pre>
<p>durch</p>
<pre class="brush: java">lifecycle = WebBeansContext.currentInstance().getService(ContainerLifecycle.class);</pre>
<p>Und der Einsatz von CDI mit OpenWebBeans in einer Java SE Umgebung steht nix mehr im Weg.</p>
<p>Zur Vollständigkeit anbei die Maven pom.xml:</p>
<pre class="brush: xml">
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;

	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
	&lt;groupId&gt;com.haddouti.maven&lt;/groupId&gt;
	&lt;artifactId&gt;cdi-test&lt;/artifactId&gt;
	&lt;packaging&gt;jar&lt;/packaging&gt;
	&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
	&lt;name&gt;cdi-test&lt;/name&gt;

	&lt;url&gt;http://www.haddouti.com&lt;/url&gt;

	&lt;dependencies&gt;

		&lt;!-- CDI Impl: Apache OpenWebBeans --&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.apache.openwebbeans&lt;/groupId&gt;
			&lt;artifactId&gt;openwebbeans-impl&lt;/artifactId&gt;
			&lt;version&gt;1.1.2&lt;/version&gt;
		&lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;org.apache.geronimo.specs&lt;/groupId&gt;
            &lt;artifactId&gt;geronimo-el_2.2_spec&lt;/artifactId&gt;
            &lt;version&gt;1.0.2&lt;/version&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;org.apache.geronimo.specs&lt;/groupId&gt;
            &lt;artifactId&gt;geronimo-interceptor_1.1_spec&lt;/artifactId&gt;
            &lt;version&gt;1.0&lt;/version&gt;
            &lt;optional&gt;true&lt;/optional&gt;
        &lt;/dependency&gt;

		&lt;!-- JSR-299 --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.apache.geronimo.specs&lt;/groupId&gt;
            &lt;artifactId&gt;geronimo-jcdi_1.0_spec&lt;/artifactId&gt;
            &lt;version&gt;1.0&lt;/version&gt;
            &lt;optional&gt;true&lt;/optional&gt;
        &lt;/dependency&gt;

		&lt;!-- JSR-330 --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.apache.geronimo.specs&lt;/groupId&gt;
            &lt;artifactId&gt;geronimo-atinject_1.0_spec&lt;/artifactId&gt;
            &lt;version&gt;1.0&lt;/version&gt;
            &lt;optional&gt;true&lt;/optional&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;org.apache.openwebbeans&lt;/groupId&gt;
            &lt;artifactId&gt;openwebbeans-spi&lt;/artifactId&gt;
            &lt;version&gt;1.1.2&lt;/version&gt;
        &lt;/dependency&gt;

	&lt;/dependencies&gt;
&lt;/project&gt;
</pre>
<p>[1] <url>http://www.jcp.org/en/jsr/summary?id=299</url><br />
[2] <url>http://blog.namics.com/2011/01/cdi-leichtgewic.html</url><br />
[3] <url>http://matthiaswessendorf.wordpress.com/2010/01/19/dependency-injection-the-jsr-330-way/</url><br />
[4] <url>http://www.adam-bien.com/roller/abien/entry/simplest_possible_ejb_3_15</url><br />
[5] <url>http://seamframework.org/Weld</url><br />
[6] <url>http://openwebbeans.apache.org/owb/index.html</url><br />
[7] <url>http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html/environments.html#d0e5333</url><br />
[8] <url>http://svn.apache.org/repos/asf/openwebbeans/trunk/samples/standalone-sample/src/main/java/org/apache/webbeans/se/sample/Boot.java</url></p>
]]></content:encoded>
			<wfw:commentRss>http://my.center-of.info/2011/10/22/cdi-in-javase/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>REST JMX Monitoring</title>
		<link>http://my.center-of.info/2011/05/03/rest-jmx-monitoring/</link>
		<comments>http://my.center-of.info/2011/05/03/rest-jmx-monitoring/#comments</comments>
		<pubDate>Mon, 02 May 2011 23:17:02 +0000</pubDate>
		<dc:creator>Haf</dc:creator>
				<category><![CDATA[JEE]]></category>
		<category><![CDATA[jee6]]></category>
		<category><![CDATA[jmx]]></category>
		<category><![CDATA[rest]]></category>

		<guid isPermaLink="false">http://my.center-of.info/?p=184</guid>
		<description><![CDATA[Ich bin wieder auf der JAX und auch bei Adam Bien. Beides ist nur zu empfehlen! Während des Workshops kamen wir auf REST und JMX und das es eigentlich eine gute Idee wäre, JMX Monitoring mittels REST anzubieten. Klingt interessant. Sofort ausprobiert. Mit Eclipse mal fix ein dynamisches Webprojekt erstellt. Drauf geachtet, dass REST (JAX-RS) [...]]]></description>
			<content:encoded><![CDATA[<p>Ich bin wieder auf der <a href="http://jax.de/">JAX</a> und auch bei <a href="http://adam-bien.com/roller/abien/">Adam Bien</a>. Beides ist nur zu empfehlen! <img src='http://my.center-of.info/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /><br />
Während des Workshops kamen wir auf REST und JMX und das es eigentlich eine gute Idee wäre, JMX Monitoring mittels REST anzubieten.<br />
Klingt interessant. Sofort ausprobiert.</p>
<p><span id="more-184"></span></p>
<p>Mit Eclipse mal fix ein dynamisches Webprojekt erstellt. Drauf geachtet, dass REST (JAX-RS) ausgewählt wird. <a href="http://glassfish.java.net/">Glassfish</a> ist schon vom letzten Projekt in Eclipse integriert.<br />
Während der Projekterstellung bietet der Wizard u.a. die Konfiguration für REST an. Da kann u.a. das URL matching pattern eingeben werden (default: /rest/*)</p>
<p>Als erstes erstellen wir eine REST-Klasse die alle MBeans auflisten. </p>
<pre class="brush: java">
import java.lang.management.ManagementFactory;
import java.util.Set;

import javax.management.MBeanServer;
import javax.management.ObjectInstance;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

/**
 * REST JMX Monitor
 *
 * @author haf
 *
 */
@Path(&quot;rjm&quot;)
public class RestJmxMonitor {

	@GET
	@Path(&quot;all&quot;)
	public String getAllMBeans() {

		MBeanServer mbServer = ManagementFactory.getPlatformMBeanServer();
		Set&lt;ObjectInstance&gt; mbeans = mbServer.queryMBeans(null, null);
		StringBuilder sb = new StringBuilder();
		sb.append(&quot;MBeans:&lt;br /&gt;&quot;);
		for(ObjectInstance oi: mbeans) {
			sb.append(oi.getObjectName());
//			sb.append(&quot; - &quot;);
//			sb.append(oi.getClassName());
			sb.append(&quot;&lt;br /&gt;&quot;);
		}

		return sb.toString();
	}
}
</pre>
<p>Glassfish starten. URL <code>http://localhost:8080/JmxMonitor/rest/rjm/all</code> aufrufen und die ObjectNames der MBeans begutachten.<br />
Vielleicht noch ein paar Worte zu den ObjectNames. Diese identifizieren ein MBean eindeutig und hat folgendes Format:<br />
Domain-name:key1=value1[,key2=value2,...keyX=valueX]<br />
Weitere Details unter <a href="http://download.oracle.com/javase/6/docs/api/javax/management/ObjectName.html">ObjectName</a>.</p>
<p>Um z.B. die Attribute für ein bestimmten MBean anzuzeigen, kann man folgende Methode anbieten:</p>
<pre class="brush: java">
@GET
	@Path(&quot;mb/{objectName : .+}&quot;)
	public String getMBean(@PathParam(&quot;objectName&quot;) String objectName) {

		MBeanServer mbServer = ManagementFactory.getPlatformMBeanServer();
		StringBuilder sb = new StringBuilder();
		try {
			Set&lt;ObjectInstance&gt; mbeans = mbServer.queryMBeans(new ObjectName(objectName), null);
			sb.append(&quot;MBeans:&lt;br /&gt;&quot;);
			for(ObjectInstance oi: mbeans) {
				sb.append(oi.getObjectName());
				sb.append(&quot;&lt;br /&gt;&quot;);
				final MBeanAttributeInfo[] attributes = mbServer.getMBeanInfo(oi.getObjectName()).getAttributes();
				sb.append(&quot;Attributes:&lt;br /&gt;&quot;);
                for (final MBeanAttributeInfo attribute : attributes) {
                	sb.append(&quot;- &quot;);
                	sb.append(attribute.getType());
                	sb.append(&quot; &quot;);
                	sb.append(attribute.getName());
                	sb.append(&quot;=&quot;);

                	Object value;
					try {
						value = mbServer.getAttribute(oi.getObjectName(), attribute.getName());
						sb.append(value);
					} catch (AttributeNotFoundException e) {
						e.printStackTrace();
					}
                	sb.append(&quot;&lt;br /&gt;&quot;);
                }
                sb.append(&quot;&lt;br /&gt;&quot;);
			}

		} catch (MalformedObjectNameException e) {
			e.printStackTrace();
		} catch (NullPointerException e) {
			e.printStackTrace();
		} catch (IntrospectionException e) {
			e.printStackTrace();
		} catch (InstanceNotFoundException e) {
			e.printStackTrace();
		} catch (ReflectionException e) {
			e.printStackTrace();
		} catch (MBeanException e) {
			e.printStackTrace();
		}

		return sb.toString();
	}
</pre>
<p>Teste man dies z.B. mit <code>http://localhost:8080/JmxMonitor/rest/rjm/mb/com.sun.appserv:type=Loader,path=/,host=server</code> erhält man die Attribute.</p>
<p>Hier sei angemerkt, dass der PathParam mit einem Regex angegeben wird, da der ObjectName das ungültige Zeichen / beinhalten kann. Falls man kein Regex verwenden möchte, kann ein @QueryParam verwendet werden.</p>
<p>Wie man sehen kann, kann man recht fix eine rudimentäre Implementierung eines JMX Monitor mit REST realisieren.<br />
Das ganze ist natürlich ausbaubar: bessere Suche (Domain, Query), andere Ausgabeformate, setzen von Werten etc.</p>
<p>Nächster Teil folgt.</p>
<p>Links:<br />
Adam Bien: <a href="http://adam-bien.com/roller/abien/">http://adam-bien.com/roller/abien/</a><br />
JSR 311: <a href="JAX-RS: The JavaTM API for RESTful Web Services: http://jcp.org/en/jsr/summary?id=311">JAX-RS: The JavaTM API for RESTful Web Services: http://jcp.org/en/jsr/summary?id=311</a><br />
JSR 339: <a href="JAX-RS 2.0: The Java API for RESTful Web Services: http://jcp.org/en/jsr/summary?id=339">JAX-RS 2.0: The Java API for RESTful Web Services: http://jcp.org/en/jsr/summary?id=339</a><br />
Glassfish: <a href="http://glassfish.java.net/">http://glassfish.java.net/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://my.center-of.info/2011/05/03/rest-jmx-monitoring/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Derby Export</title>
		<link>http://my.center-of.info/2011/04/22/derby-export/</link>
		<comments>http://my.center-of.info/2011/04/22/derby-export/#comments</comments>
		<pubDate>Fri, 22 Apr 2011 09:39:59 +0000</pubDate>
		<dc:creator>Haf</dc:creator>
				<category><![CDATA[DB]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://my.center-of.info/?p=179</guid>
		<description><![CDATA[Beim Einsatz der Java Derby Datenbank kommt irgendwann der Wunsch einzelne Daten oder eine komplette Tabelle zu exportieren. Hierfür bietet Derby verschiedene Procedures an: SYSCS_UTIL.SYSCS_EXPORT_TABLE: Zum exportieren einer kompletten Tabelle SYSCS_UTIL.SYSCS_EXPORT_QUERY: Exportiert die Daten, die dem mitgegebenen SELECT entsprechen SYSCS_UTIL.SYSCS_BACKUP_DATABASE: Kompletter Backup der DB. Die Export-Procedures liefern eine CSV-Datei, wobei man die Trennzeichen definieren kann. [...]]]></description>
			<content:encoded><![CDATA[<p>Beim Einsatz der Java Derby Datenbank kommt irgendwann der Wunsch einzelne Daten oder eine komplette Tabelle zu exportieren. Hierfür bietet Derby verschiedene Procedures an:</p>
<ul>
<li>SYSCS_UTIL.SYSCS_EXPORT_TABLE: Zum exportieren einer kompletten Tabelle</li>
<li>SYSCS_UTIL.SYSCS_EXPORT_QUERY: Exportiert die Daten, die dem mitgegebenen SELECT entsprechen</li>
<li>SYSCS_UTIL.SYSCS_BACKUP_DATABASE: Kompletter Backup der DB.</li>
</ul>
<p><span id="more-179"></span></p>
<p>Die Export-Procedures liefern eine CSV-Datei, wobei man die Trennzeichen definieren kann.<br />
Beim Backup-Procedure wird die ganze Ordnerstruktur in einen gewünschten Ordner kopiert.</p>
<p>Zum Exportieren einer ganzen Tabelle sieht die Signatur der Procedure wie folgt aus:</p>
<pre class="brush: sql">
SYSCS_UTIL.SYSCS_EXPORT_TABLE (
	IN SCHEMANAME  VARCHAR(128),
	IN TABLENAME VARCHAR(128),
	IN FILENAME VARCHAR(32672),
	IN COLUMNDELIMITER CHAR(1),
	IN CHARACTERDELIMITER CHAR(1),
	IN CODESET VARCHAR(128)
)
</pre>
<p>&#8230;für eine definierte Datenmenge</p>
<pre class="brush: sql">
SYSCS_UTIL.SYSCS_EXPORT_QUERY(
	IN SELECTSTATEMENT VARCHAR(32672),
	IN FILENAME VARCHAR(32672),
	IN COLUMNDELIMITER CHAR(1),
	IN CHARACTERDELIMITER CHAR(1),
	IN CODESET VARCHAR(128)
)
</pre>
<p>Beispielhaft (mit JPA)</p>
<pre class="brush: java">
public void exportTable()
{
	final Object[] paras = new Object[6];
	paras[0] = „DB-SCHEMA“;
	paras[1] = „TABLE-NAME“;
	paras[2] = „EXPORT-FILE-PATH.csv“;
	// Column delimiter
	paras[3] = &#039;;&#039;;
	// character delimiter
	paras[4] = &#039;|&#039;;
	// Codeset
	paras[5] = „UTF-8“;

	callProcedure(„{call SYSCS_UTIL.SYSCS_EXPORT_TABLE (?,?,?,?,?,?)}“, paras);
}

public void exportData()
{
	final Object[] paras = new Object[5];
	paras[0] = „SELECT * FROM TABLE-NAME WHERE id IN (1, 2, 99) AND ...“;
	paras[1] = „EXPORT-FILE-PATH.csv“;
	// Column delimiter
	paras[2] = &#039;;&#039;;
	// character delimiter
	paras[3] = &#039;|&#039;;
	// Codeset
	paras[4] = „UTF-8“;

	callProcedure(„{call SYSCS_UTIL.SYSCS_EXPORT_TABLE (?,?,?,?,?,?)}“, paras);
}

public void callProcedure(final String sql, final Object... parameters)
{
	final Query query = entityManager.createNativeQuery(sql);
	int counter = 1;
	for(Object o: parameters)
	{
		query.setParameter(i++, o);
	}

}
</pre>
<p>Links:</p>
<ul>
<li>Derby DB: <a href="http://db.apache.org/derby/">http://db.apache.org/derby/</a></li>
<li>Derby Referenz Guide &#8211; Export Data: <a href="http://db.apache.org/derby/docs/10.7/ref/ref-single.html#rrefexportselectionproc">http://db.apache.org/derby/docs/10.7/ref/ref-single.html#rrefexportselectionproc</a>
</li>
<li>Derby Referenz Guide – Export Table: <a href="http://db.apache.org/derby/docs/10.7/ref/ref-single.html#rrefexportproc">http://db.apache.org/derby/docs/10.7/ref/ref-single.html#rrefexportproc</a></li>
<li>Derby Referenz Guide – Backup: <a href="http://db.apache.org/derby/docs/10.7/ref/ref-single.html#rrefbackupdbproc">http://db.apache.org/derby/docs/10.7/ref/ref-single.html#rrefbackupdbproc</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://my.center-of.info/2011/04/22/derby-export/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JPA: Dynamic Datasource Routing</title>
		<link>http://my.center-of.info/2011/03/04/jpa-dynamic-datasource-routing/</link>
		<comments>http://my.center-of.info/2011/03/04/jpa-dynamic-datasource-routing/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 20:15:54 +0000</pubDate>
		<dc:creator>Haf</dc:creator>
				<category><![CDATA[DB]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://my.center-of.info/?p=158</guid>
		<description><![CDATA[Man stelle sich vor, in einer (Web-)Anwendung müssen verschiedene Datasources verwendet werden. Ob bei den unterschiedlichen Datasourcen es sich immer um die andere/gleiche Datenbank handelt, sei mal dahingestellt. Die Datasourcen unterscheiden sich mind. in einer Eigenschaft, z.B. User. Im Spring-Kontext gilt folgendes: In JPA braucht man pro EntityManagerFactory eine Datasource. Der EMF ist einen TransactionManager [...]]]></description>
			<content:encoded><![CDATA[<p>Man stelle sich vor, in einer (Web-)Anwendung müssen verschiedene Datasources verwendet werden. Ob bei den unterschiedlichen Datasourcen es sich immer um die andere/gleiche Datenbank handelt, sei mal dahingestellt. Die Datasourcen unterscheiden sich mind. in einer Eigenschaft, z.B. User.</p>
<p><span id="more-158"></span></p>
<p>Im Spring-Kontext gilt folgendes: In JPA braucht man pro EntityManagerFactory eine Datasource. Der EMF ist einen TransactionManager zugeordnet.</p>
<p>Man könnte alle Datasource, EMF, TX-Manager und PUs in Spring konfigurieren. Man hat jedoch ein Problem, wenn man n verschiedene Datasourcen hat, die zur Laufzeit ausgewählt werden müssen.</p>
<ul>
<li>Die Konfiguration ist umfangreich und unübersichtlich
<ul>
<li>Pro Datasource ist ein Persistence-Unit notwendig, denn für die Ermittlung des richtigen EntityManager kann @<a title="JEE 5 API: PersistenceContext" href="http://download.oracle.com/javaee/5/api/javax/persistence/PersistenceContext.html" target="_blank">PersistenceContext</a>(unitName = &#8220;PU_NAME&#8221;) verwendet werden</li>
<li>Pro Datasource einen EntityManagerFactory mit der Verknüpfung zur PersistenceUnit</li>
<li>Pro EntityManagerFactory einen TransactionManager, ggf. mit <a title="Spring 3 Reference Doc: Qualifier" href="http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-autowired-annotation-qualifiers" target="_blank">Qualifier</a>.</li>
</ul>
</li>
<li>Die Wartung ist entsprechend nicht optimal. Pro neue Datasource müssen 3 Stellen angepasst werden</li>
<li>Das Transaction-Handling wird kompliziert. @<a title="Spring 3 API: Transactional" href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/transaction/annotation/Transactional.html" target="_blank">Transactional</a> muss nun immer den richtigen TransactionManager nutzen. Die Entscheidung soll natürlich zur Laufzeit passieren. @Transactional(&#8220;TX_MANAGER_NAME&#8221;) reicht nicht aus, da es eine statische Kopplung verursacht.</li>
</ul>
<p>Eine andere Lösungsvariante wäre, statt einen <a title="JEE 5 API: EntityManager" href="http://download.oracle.com/javaee/5/api/javax/persistence/EntityManager.html">EntityManager</a> durch @PersitenceContext eher direkt den <a title="JEE 5 API: EntityManagerFactory" href="http://download.oracle.com/javaee/5/api/javax/persistence/EntityManagerFactory.html">EntityManagerFactory</a> durch @<a title="JEE 5 API: PersistenceUnit" href="http://download.oracle.com/javaee/5/api/javax/persistence/PersistenceUnit.html">PersistenceUnit</a> zu bekommen. Hier modifiziert man die EntityManager-Erstellung soweit, dass man den EntityManager mit der gewünschten Datasource bekommt. Falls sich bei den Datasourcen nur die User unterscheiden und <a title="Eclipselink JPA" href="http://www.eclipse.org/eclipselink/jpa.php" target="_blank">Eclipselink</a> verwendet wird, siehe u.a. [1].</p>
<p>Perfekt wäre jedoch eine Lösung, in der nur EntityManagerFactory, ein TransactionManager und ein PersistenceUnit verwendet wird. Zur Laufzeit soll dann der vorhandene EntityManagerFactory für die gewünschte Datasource einen EntityManager erstellen.</p>
<p>Das funktioniert. Der EntityManagerFactory erwartet eine Referenz auf die <a title="Java 5 API: DataSource" href="http://download.oracle.com/javase/1.5.0/docs/api/javax/sql/DataSource.html" target="_blank">DataSource</a>. Hier könnte man eine eigene Implementierung dieses Interface anbieten, welches die Unterscheidung bzgl. der verschiedenen Datasourcen durchführt. DataSource.getConnection() muss dann abhängig von fest definierten Eigenschaften die Connection von der richtigen Datasource zurückgeben. Um die Eigenschaften in der eigenen DataSource-Implementierung abzufragen, ist die Nutzung von <a title="Java 5 API: ThreadLocal" href="http://download.oracle.com/javase/1.5.0/docs/api/java/lang/ThreadLocal.html" target="_blank">ThreadLocal</a> bzw. <a title="Java 5 API: InheritableThreadLocal" href="http://download.oracle.com/javase/1.5.0/docs/api/java/lang/InheritableThreadLocal.html" target="_blank">InheritableThreadLocal</a> möglich.</p>
<p>Eine Spring-spezifische Lösung die in diese Richtung geht, ist mittels <a title="Spring 3 API: AbstractRoutingDataSource" href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.html" target="_blank">AbstractRoutingDatasource</a> möglich [2]. Hier muss die abstrakte Methode determineCurrentLookupKey() implementiert werden. In dieser Methode muss die Logik verpackt werden, damit anhand des resultierenden Keys die richtige Datasource verwendet werden kann. Das Mapping zwischen Key und Datasource wird in AbstractRoutingDatasources#<a title="Spring 3 API: AbstractRoutingDataSource.setTargetDataSources()" href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.html#setTargetDataSources(java.util.Map)" target="_blank">targetDataSources</a> gehalten. Wird kein Key zurückgeliefert, wird die vorher definierte Standard-Datasource verwendet.</p>
<p>Eine Beispiel-Implementierung, welches mit Spring 3.x und jeweils mit Eclipselink und Hibernate funktioniert, sieht wie folgt aus:</p>
<p>Die relevante Spring-Konfiguration:</p>
<pre class="brush: xml">
&lt;bean id=&quot;baseDataSource&quot; abstract=&quot;true&quot;&gt;
&lt;property name=&quot;driverClassName&quot; value=&quot;${db.driverClassName}&quot;/&gt;
&lt;property name=&quot;url&quot; value=&quot;${db.url}&quot;/&gt;
&lt;/bean&gt;

&lt;bean id=&quot;dataSource1&quot; parent=&quot;baseDataSource&quot;&gt;
&lt;property name=&quot;user&quot; value=&quot;${db.1.user}&quot;/&gt;
&lt;property name=&quot;password&quot; value=&quot;${db.1.pw}&quot;/&gt;
&lt;/bean&gt;
&lt;bean id=&quot;dataSource2&quot; parent=&quot;baseDataSource&quot;&gt;
&lt;property name=&quot;user&quot; value=&quot;${db.2.user}&quot;/&gt;
&lt;property name=&quot;password&quot; value=&quot;${db.2.pw}&quot;/&gt;
&lt;/bean&gt;
&lt;bean id=&quot;dataSource3&quot; parent=&quot;baseDataSource&quot;&gt;
&lt;property name=&quot;user&quot; value=&quot;${db.3.user}&quot;/&gt;
&lt;property name=&quot;password&quot; value=&quot;${db.3.pw}&quot;/&gt;
&lt;/bean&gt;

&lt;bean id=&quot;dynamicDatasource&quot; class=&quot;info.center-of.spring.jpa.DynamicDataSourceRouting&quot;&gt;
&lt;property name=&quot;targetDataSources&quot;&gt;
&lt;entry key=&quot;${db.1.user}&quot; value-ref=&quot;dataSource1&quot;/&gt;
&lt;entry key=&quot;${db.2.user}&quot; value-ref=&quot;dataSource2&quot;/&gt;
&lt;entry key=&quot;${db.3.user}&quot; value-ref=&quot;dataSource3&quot;/&gt;
&lt;/property&gt;
&lt;property name=&quot;defaultTargetDataSource&quot; ref=&quot;dataSource1&quot;/&gt;
&lt;/bean&gt;

&lt;bean id=&quot;entityManagerFactory&quot; class=&quot;org.springframework.orm.jpa.LocalEntityManagerFactoryBean&quot;&gt;
&lt;property name=&quot;datasource&quot; ref=&quot;dynamicDatasource&quot; /&gt;
&lt;property name=&quot;jpaVendorAdapter&quot;&gt;
&lt;!-- Fuer Hibernate --&gt;
&lt;bean class=&quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&quot; p:showSql=&quot;true&quot; generateDdl=&quot;true&quot; /&gt;
&lt;!-- Fuer Eclipselink
&lt;bean class=&quot;org.springframework.orm.jpa.vendor.EclipselinkJpaVendorAdapter&quot; p:showSql=&quot;true&quot; generateDdl=&quot;true&quot; /&gt;
--&gt;
&lt;/property&gt;
&lt;/bean&gt;

&lt;bean class=&quot;org.springframework.orm.jpa.JpaTransactionManager&quot;&gt;
&lt;property name=&quot;entityManagerFactory&quot; ref=&quot;entityManagerFactory&quot; /&gt;
&lt;/bean&gt;

&lt;tx:annotation-driven /&gt;
</pre>
<p>Die Klasse <em>DynamicDataSourceRouting</em> überschreibt die Methode zur Ermittlung des Keys. In unserem Fall ist dies immer der aktuelle/gewünschte DB-User:</p>
<pre class="brush: java">
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class CustomerRoutingDataSource extends AbstractRoutingDataSource {

@Override
protected Object determineCurrentLookupKey() {
return DBUserContextHolder.getDBUser();
}
}
</pre>
<p><em>DBUserContextHolder</em> ist eine Klasse mit einer ThreadLocal-Variable, die in dem aktuellen Thread den DB-User hält</p>
<pre class="brush: java">
public class DBUserContextHolder {

private static final InheritableThreadLocal&lt;String&gt; contextHolder = new InheritableThreadLocal&lt;String&gt;();

public static void setDBUser(final String dbUser) {
contextHolder.set(dbUser);
}

public static String getDBUser() {
return (String) contextHolder.get();
}

public static void clear() {
contextHolder.remove();
}
}
</pre>
<p>Bevor der EntityManager nun erstellt wird, muss</p>
<pre class="brush: java">
DBUserContextHolder.setDBUser(&amp;quot;dbUser1&amp;quot;);
</pre>
<p>aufgerufen werden.</p>
<p>Mit dieser Lösung hat man &#8220;nur&#8221; eine enge Kopplung mit Spring. Die Lösung funktioniert mit verschiedenen ORMs.</p>
<p>&nbsp;</p>
<p>[1]: <a title="Wikibook JPA: Java Persistence/Auditing and Security - Provide each application user with a database user id" href="http://en.wikibooks.org/wiki/Java_Persistence/Auditing_and_Security" target="_blank">Wikibook JPA: Provide each application user with a database user id</a></p>
<p>[2]: <a title="Spring Blog: Dynamic DataSource Routing" href="http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/" target="_blank">Spring Blog: Dynamic DataSource Routing</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://my.center-of.info/2011/03/04/jpa-dynamic-datasource-routing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spring AOP &amp; Ehcache</title>
		<link>http://my.center-of.info/2009/09/25/spring-aop-ehcache/</link>
		<comments>http://my.center-of.info/2009/09/25/spring-aop-ehcache/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 14:27:59 +0000</pubDate>
		<dc:creator>Haf</dc:creator>
				<category><![CDATA[JEE]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[aop]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://my.center-of.info/?p=145</guid>
		<description><![CDATA[Caching ist ja bekanntlich eine Querschnitts-Anforderung (cross cutting concern), was man eigentlich nicht direkt in die Business-Logik integrieren möchte/sollte. Hier bietet es sich an, die Cache-Funktionalität mittels AOP (Aspektorientierte Programmierung) zu realisieren. Dieser Beitrag erklärt das exemplarisch realisieren der Cache-Funktionalität mittels Spring AOP und Ehcache. Einführung Vorweg. Es gibt natürlich bei den springmodules ein Cache-Modul. [...]]]></description>
			<content:encoded><![CDATA[<p>Caching ist ja bekanntlich eine Querschnitts-Anforderung (cross cutting concern), was man eigentlich nicht direkt in die Business-Logik integrieren möchte/sollte.<br />
Hier bietet es sich an, die Cache-Funktionalität mittels AOP (Aspektorientierte Programmierung) zu realisieren.<br />
Dieser Beitrag erklärt das exemplarisch realisieren der Cache-Funktionalität mittels <a href="http://static.springsource.org/spring/docs/2.5.x/reference/aop-api.html" target="_blank" title="Spring 2.5.x Reference Doc: Spring AOP">Spring AOP</a> und <a href="http://ehcache.org/" target="_blank" title="Ehcache">Ehcache</a>.<br />
<span id="more-145"></span><br />
<strong>Einführung</strong><br />
Vorweg. Es gibt natürlich bei den <a href="https://springmodules.dev.java.net/" target="_blank" title="Springmodules">springmodules</a> ein <a href="https://springmodules.dev.java.net/docs/reference/0.9/html/cache.html" target="_blank" title="Springmodules: Cache">Cache-Modul</a>. Dieses wird, wenn überhaupt, nur sehr langsam weiterentwickelt. Das neue <a href="http://www.springsource.org/extensions" target="_blank" title="Spring Source: Spring Extensions">Spring Extensions Projekt</a> beinhaltet leider kein Cache-Modul. Hinzu kommen noch fehlende Funktionalitäten wie z.B. das Löschen von nur einem Objekt aus dem Cache.<br />
Falls man jedoch doch Springmodules Cache nutzen will, kann man sich mein altes <a href="http://my.center-of.info/2009/04/07/cache-method-results-with-ehcache-and-spring/" target="_blank" title="Centre of information: Cache method results with Ehcache and Spring">Beispiel</a> anschauen.</p>
<p><strong>Technologie</strong><br />
In der Lösung wird nur Spring AOP und Ehcache direkt verwendet. Bei der AOP Implementierung wird nicht <a href="http://www.eclipse.org/aspectj/" target="_blank" title="Eclipse: AspectJ Project">AspectJ</a> verwendet um die Anzahl der abhängigen Bibliotheken gering zu halten. Dies ist auch möglich, da die benötigte Funktionalität durch <a href="http://static.springsource.org/spring/docs/2.5.x/reference/aop-api.html" target="_blank" title="Spring 2.5.x Reference Doc: Spring AOP">Spring AOP</a> bereitgestellt wird.<br />
Mittels der Spring-Klasse <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.html" target="_blank" title="Spring 2.5.x API: EhCacheManagerFactoryBean">EhCacheManagerFactoryBean</a> wird der Ehcache integriert.</p>
<p><strong>Bibliotheken</strong><br />
In diesem Fall braucht man mindestens (und die entsprechende Abhängigkeiten):</p>
<ul>
<li>spring 2.5.6</li>
<li>ehcache</li>
</ul>
<p><strong>XML Konfiguration</strong><br />
Die XML Konfiguration für Spring sieht wie folgt aus:</p>
<pre class="brush: xml">
 &lt;!-- ...some other spring configuration... --&gt;

 &lt;!-- Ehcache bean which gets the path the ehcache.xml config file --&gt;
 &lt;bean id=&quot;cacheManager&quot; class=&quot;org.springframework.cache.ehcache.EhCacheManagerFactoryBean&quot;&gt;
        &lt;property name=&quot;configLocation&quot; value=&quot;classpath:ehcache.xml&quot; /&gt;
    &lt;/bean&gt;

 &lt;!-- Interceptor which handels the cross cutting concerns (here: caching) --&gt;
 &lt;bean id=&quot;coInterceptor&quot; class=&quot;de.ic.jee.aop.COCacheInterceptor&quot;&gt;
		&lt;constructor-arg index=&quot;0&quot; ref=&quot;cacheManager&quot; /&gt;
  		&lt;!-- Set the name of the cache which will be used from the cache manager --&gt;
		&lt;constructor-arg index=&quot;1&quot; value=&quot;coCache&quot; /&gt;
	&lt;/bean&gt;

  &lt;!-- Advisor for the relevant methods --&gt;
    &lt;bean id=&quot;coAdvisor&quot; class=&quot;org.springframework.aop.support.RegexpMethodPointcutAdvisor&quot;&gt;
		&lt;property name=&quot;advice&quot;&gt;
        	&lt;ref local=&quot;coInterceptor&quot;/&gt;
		&lt;/property&gt;
		&lt;property name=&quot;patterns&quot;&gt;
                  &lt;!-- only the get and update methods --&gt;
        	  &lt;list&gt;
        		&lt;value&gt;.*update.*&lt;/value&gt;
        		&lt;value&gt;.*get.*&lt;/value&gt;
        	  &lt;/list&gt;
		&lt;/property&gt;
	&lt;/bean&gt;

  &lt;!-- Proxy factory for aop proxy  --&gt;
	&lt;bean id=&quot;coServiceProxy&quot; class=&quot;org.springframework.aop.framework.ProxyFactoryBean&quot;&gt;
		&lt;property name=&quot;target&quot;&gt;
                        &lt;!-- The target bean object --&gt;
			&lt;ref bean=&quot;coService&quot;/&gt;
		&lt;/property&gt;
		&lt;property name=&quot;interceptorNames&quot;&gt;
			&lt;list&gt;
				&lt;value&gt;coAdvisor&lt;/value&gt;
			&lt;/list&gt;
		&lt;/property&gt;
                &lt;!-- Name of this new generated proxy, to identify this object
                       in the autowired process.
                --&gt;
		&lt;qualifier value=&quot;coServiceProxy&quot;/&gt;
	&lt;/bean&gt;
</pre>
<p>Spring AOP ist <a href="http://static.springsource.org/spring/docs/2.5.x/reference/aop.html#aop-introduction-proxies" target="_blank" title="Spring 2.5.x Reference Doc: 6.1.3. AOP Proxies">proxy-basiert</a>. Hierfür wird deswegen ein <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/aop/framework/ProxyFactoryBean.html" target="_blank" title="Spring 2.5.x API: ProxyFactoryBean">ProxyFactoryBean</a> definiert, was den Advisor (<code>coAdvisor</code>) auf ein bestimmtes Bean einsetzt, somit entsteht dann eine neue Proxy-Klasse (<code>coServiceProxy</code>).</p>
<p>Mit <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/aop/support/RegexpMethodPointcutAdvisor.html" target="_blank" title="Spring 2.5.x API: RegexpMethodPointcutAdvisor">RegexpMethodPointcutAdvisor</a> kann definiert werden, welche Methoden beobachtet werden. In unserem Fall alle <code>update</code> und <code>get</code> Methoden.</p>
<p>Der Advice bzw. Interceptor (<code>coInterceptor</code>), welcher die Querschnitts-Funktionalität beinhaltet, kriegt eine Referenz auf den CacheManager (hier: <code>cacheManager</code>). Mit dieser Referenz kann beim Methoden-Aufruf vorher im Cache geprüft werden, ob die Antwort schon bekannt ist, wenn nicht, wird die Methode weiter ausgeführt und das Ergebnis (Rückgabewert) dann im Cache gespeichert.</p>
<pre class="brush: java">
public class COCacheInterceptor implements MethodInterceptor {

    private final CacheManager cacheManager;
    public COCacheInterceptor(final CacheManager cm, final String cn) {
		this.cacheManager = cm;
		this.cacheName = cn;
	}

     public Object invoke(final MethodInvocation methodInvocation) throws Throwable {

          /*
           * Cache cache = cacheManager.getCache(this.cacheName);
           * String cacheKey = .... generate cache key, maybe the arguments of the method invocation
           * get element from the cache
           * Element e = cache.get(cacheKey);
           * If element found:
           * - return e.getObjectValue()
           * otherwise:
           * - proceed the method, methodResult = methodInvocation.proceed()
           * - put the result in the cache, cache.put(new Element(cacheKey, methodResult));
           * - return methodResult;
           */

     } // invoke()
}
</pre>
<p>Mit wenig Konfiguration und Programmierung kann man sehr einfach Cache-Funktionalität einfügen, ohne die Business Logik zu verändern.</p>
<p>Links:<br />
- Spring AOP: <a href="http://static.springsource.org/spring/docs/2.5.x/reference/aop-api.html" target="_blank">http://static.springsource.org/spring/docs/2.5.x/reference/aop-api.html</a><br />
- Ehcache: <a href="http://ehcache.org/" target="_blank">http://ehcache.org/</a><br />
- Spring 2.5.x API: <a href="http://static.springsource.org/spring/docs/2.5.x/api/index.html" target="_blank">http://static.springsource.org/spring/docs/2.5.x/api/index.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://my.center-of.info/2009/09/25/spring-aop-ehcache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tutorial: JSF 2.0 Beispielanwendung</title>
		<link>http://my.center-of.info/2009/08/27/tutorial-jsf2-beipielanwendung/</link>
		<comments>http://my.center-of.info/2009/08/27/tutorial-jsf2-beipielanwendung/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 22:22:39 +0000</pubDate>
		<dc:creator>Haf</dc:creator>
				<category><![CDATA[JEE]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[jsf2]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://my.center-of.info/?p=138</guid>
		<description><![CDATA[Wie schon erwähnt, erscheinen bald die ersten Releases von JSF 2.0. Entsprechend wird nun eine kleine Beispielanwendung erstellt, um einen ersten Eindruck zu bekommen. Technologie: JSF 2.0: Mojarra in Version 2.0.0-b16 Tomcat 6 Maven Eclipse Voraussetzung: JDK 6 Tomcat 6 Eclipse inklusive WTP, Maven (m2eclipse) Beim m2eclipse-Plugin &#8220;Maven integration for WTP&#8221; in Eclipse nachinstallieren, falls [...]]]></description>
			<content:encoded><![CDATA[<p>Wie schon <a href="http://my.center-of.info/2009/08/26/jsf2overview/" title="IC: JSF 2 Überblick">erwähnt</a>, erscheinen bald die ersten Releases von JSF 2.0.<br />
Entsprechend wird nun eine kleine Beispielanwendung erstellt, um einen ersten Eindruck zu bekommen.<br />
Technologie:</p>
<ul>
<li>JSF 2.0: Mojarra in Version 2.0.0-b16</li>
<li>Tomcat 6</li>
<li>Maven</li>
<li>Eclipse</li>
</ul>
<p><span id="more-138"></span><br />
<strong>Voraussetzung:</strong></p>
<ul>
<li><a href="http://java.sun.com/javase/downloads/index.jsp" target="_blank" title="SUN: Java Download">JDK 6</a></li>
<li><a href="http://tomcat.apache.org/download-60.cgi" target="_blank" title="Apache Tomcat 6 Download">Tomcat 6</a></li>
<li><a href="http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/galileor" target="_blank" title="Eclipse Download: Galileor">Eclipse inklusive WTP</a>, Maven (<a href="http://m2eclipse.sonatype.org/" target="_blank" title="Sonatype: Maven Eclipse Plugin">m2eclipse</a>)</li>
<li>Beim m2eclipse-Plugin &#8220;<strong>Maven integration for WTP</strong>&#8221; in Eclipse nachinstallieren, falls nicht vorhanden</li>
</ul>
<p><strong>Vorbereitung:</strong></p>
<ol>
<li>In Eclipse ein dynamische Webprojekt erstellen</li>
<li>Tomcat 6 als Server in Eclipse einrichten</li>
<li>Dem Projekt &#8220;Maven Nature&#8221; hinzufügen. Zur Zeit ist das Projekt ein reines Webprojekt ohne Maven Eigenschaften. Durch Rechte-Maustaste auf das Projekt und dann <em>Maven > Enable Dependency Management</em> wird Maven-Funktionalität für das Projekt hinzugefügt</li>
<li>Maven erwartet eine andere Ordner-Struktur als in dem WTP-Webprojekt. Als erstes muss der Source-Ordner angepasst werden. Hierfür müssen mind. folgender Ordner erstellt werden: src/main/java. Diesen muss man in Eclipse dann auch als Source-Ordner konfigurieren (Java Build Path)</li>
<li>Der WebContent-Ordner wird von Maven mit der WTP-Integration genutzt. Hier ist keine Veränderung/Anpassung notwendig</li>
<li>Die existierende pom.xml muss entsprechende Einträge erweitert werden. Für JSF 2 könnte das wie folgt aussehen:
<pre class="brush: xml">
&lt;project xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&amp;quot;&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;jsf2test&lt;/groupId&gt;
  &lt;artifactId&gt;jsf2test&lt;/artifactId&gt;
  &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;

  &lt;properties&gt;
  	&lt;version.jsf2&gt;2.0.0-b16&lt;/version.jsf2&gt;
  	&lt;version.junit&gt;4.4&lt;/version.junit&gt;
  	&lt;version.jstl&gt;1.2&lt;/version.jstl&gt;
  	&lt;version.servlet&gt;2.5&lt;/version.servlet&gt;
  	&lt;version.log4j&gt;1.2.14&lt;/version.log4j&gt;
  &lt;/properties&gt;

  &lt;repositories&gt;
  	&lt;repository&gt;
		&lt;id&gt;maven2-repository.dev.java.net&lt;/id&gt;
		&lt;name&gt;Java.net Repository for Maven&lt;/name&gt;
		&lt;url&gt;http://download.java.net/maven/2/&lt;/url&gt;
		&lt;layout&gt;default&lt;/layout&gt;
	&lt;/repository&gt;
  &lt;/repositories&gt;

  &lt;build&gt;
    &lt;finalName&gt;jsf2test&lt;/finalName&gt;
    &lt;plugins&gt;
	    &lt;plugin&gt;
			&lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
			&lt;configuration&gt;
			&lt;source&gt;1.5&lt;/source&gt;
			&lt;target&gt;1.5&lt;/target&gt;
			&lt;/configuration&gt;
		&lt;/plugin&gt;

	    &lt;plugin&gt;
		  &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
		  &lt;!-- jetty 7
		  &lt;artifactId&gt;jetty-maven-plugin&lt;/artifactId&gt;
		   --&gt;
		  &lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
		  &lt;version&gt;6.1.15&lt;/version&gt;
		  &lt;!--
		  &lt;configuration&gt;
		    &lt;scanIntervalSeconds&gt;10&lt;/scanIntervalSeconds&gt;
		  &lt;/configuration&gt;
		   --&gt;
		&lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;

   &lt;dependencies&gt;
   	&lt;!-- JSF2 --&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;com.sun.faces&lt;/groupId&gt;
		&lt;artifactId&gt;jsf-api&lt;/artifactId&gt;
		&lt;version&gt;${version.jsf2}&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;com.sun.faces&lt;/groupId&gt;
		&lt;artifactId&gt;jsf-impl&lt;/artifactId&gt;
		&lt;version&gt;${version.jsf2}&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
      &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
      &lt;artifactId&gt;jstl&lt;/artifactId&gt;
      &lt;version&gt;${version.jstl}&lt;/version&gt;
    &lt;/dependency&gt;

    &lt;dependency&gt;
      &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
      &lt;artifactId&gt;servlet-api&lt;/artifactId&gt;
      &lt;version&gt;${version.servlet}&lt;/version&gt;
    &lt;/dependency&gt;

	&lt;!-- Misc --&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;junit&lt;/groupId&gt;
      &lt;artifactId&gt;junit&lt;/artifactId&gt;
      &lt;version&gt;${version.junit}&lt;/version&gt;
      &lt;scope&gt;test&lt;/scope&gt;
    &lt;/dependency&gt;

    &lt;dependency&gt;
	    &lt;groupId&gt;log4j&lt;/groupId&gt;
	    &lt;artifactId&gt;log4j&lt;/artifactId&gt;
	    &lt;version&gt;${version.log4j}&lt;/version&gt;
	&lt;/dependency&gt;

  &lt;/dependencies&gt;
&lt;/project&gt;
</pre>
</li>
<li>Die Bibliotheken, welche Maven bereitstellt, müssen beim Deploy in WEB/lib kopiert werden. Die Nutzung der Maven Dependencies geschieht durch folgende Einstellung: In den Eigenschaften des Projekts muss unter <strong>Java EE Module Dependencies</strong> die <strong>Maven Dependencies</strong> ausgewählt werden.</li>
<li>Web.xml für JSF anpassen. Z.B. wie folgt:
<pre class="brush: xml">
&lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&gt;
&lt;web-app xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/javaee&amp;quot; xmlns:web=&amp;quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;quot; xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;quot; id=&amp;quot;WebApp_ID&amp;quot; version=&amp;quot;2.5&amp;quot;&gt;
  &lt;display-name&gt;dynWebTest&lt;/display-name&gt;

  &lt;servlet&gt;
    &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
    &lt;servlet-class&gt;javax.faces.webapp.FacesServlet&lt;/servlet-class&gt;
    &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
  &lt;/servlet&gt;

  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
    &lt;url-pattern&gt;*.xhtml&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;

  &lt;!-- This parameter is also possible to set over JNDI --&gt;
  &lt;context-param&gt;
    &lt;param-name&gt;javax.faces.PROJECT_STAGE&lt;/param-name&gt;
    &lt;param-value&gt;Development&lt;/param-value&gt;
  &lt;/context-param&gt;

  &lt;welcome-file-list&gt;
    &lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
    &lt;welcome-file&gt;index.xhtml&lt;/welcome-file&gt;
  &lt;/welcome-file-list&gt;
&lt;/web-app&gt;
</pre>
</li>
</ol>
<p>Nun steht das Grundgerüst bereit, um endlich mit JSF 2.0 anzufangen.<br />
Für diejenigen, die mit JSF 1.x schon gearbeitet haben, werden wohl die faces-config.xml vermissen. Korrekt. Ist gewollt. Ist nämlich die erste Verbesserung von JSF 2.0! Die faces-config.xml kann immer noch verwendet werden, aber vieles ist durch Annotations möglich und die Navigation ist einfacher/verständlicher geworden. Später mehr dazu.</p>
<p>Vielleicht noch ein paar Worte zur Beispielanwendung: Die Beispielanwendung beinhaltet eine Seite, mit einem Input-Feld und zwei Select-Boxen. Man stelle sich folgendes Szenario vor: Man möchte ein Registrierungs-Formular erstellen, in dem der Nutzer überprüfen kann, ob der Username noch vorhanden ist. Zusätzlich soll er das Land auswählen können, in dem er lebt.</p>
<p><strong> Controller:</strong><br />
Der Controller ist das ManagedBean, welches in den XHTML-Seiten verwendet wird und alle Anfragen verarbeitet.</p>
<pre class="brush: java">
@ManagedBean(name = &amp;quot;fc&amp;quot;)
@RequestScoped
public class FrontController {

	private Person person;

	private String country;

	private String continent;

	private Map&lt;String, String[]&gt; countries;

	@ManagedProperty(value = &amp;quot;#{authService}&amp;quot;)
	private AuthService authService;

	public void isUsernameValid() {

		if(authService.isUsernameValid(person.getUsername())) {

			output = &amp;quot;Username ist nocht nicht vorhanden&amp;quot;;
		} else {
			output = &amp;quot;Username ist schon vorhanden. Bitte einen anderen auswählen&amp;quot;;
		}
	}

        public String[] getCountries() {
		// deliver the countries to the actual continent
		return countries.get(continent);
	}
       /* further get/set-Methods */
}
</pre>
<p>Durch die Annotations wird JSF mitgeteilt, dass es sich bei der Klasse um ein managed bean mit dem Namen <strong>fc</strong> handelt (@ManagedBean) und die jeweils immer nur für ein Request gültig ist (@RequestScoped, <a href="https://javaserverfaces.dev.java.net/nonav/docs/2.0/managed-bean-javadocs/" target="_blank" title="API 2.0 - Managed Bean">weitere Scops sind vorhanden</a>). Früher hat man diese Einstellungen in faces-config.xml durchgeführt.<br />
Neu ist auch @ManagedProperty. Mittels dieser Annotation wird die Dependency Injection Funktionalität von JSF 2.0 verwendet. In FrontController#authService wird nun das passende Objekt mit dem managed bean namen &#8220;authService&#8221; injiziert.<br />
Hier sei anzumerken, dass JSF kein field access durchführt, sondern die getter/setter-Methoden verwendet um Properties zu setzen.</p>
<p>Die Domain-Klasse Person ist ein einfaches Bean bzw. POJO, und repräsentiert die einzugebenden Daten in dem Formular.</p>
<p>Zu dem Controller und Model Teil gehört noch die Präsentation und diese wird mittels <a href="https://facelets.dev.java.net/" target="_blank" title="Facelets">Facelets</a> durchgeführt. In JSF 2.0 ist Facelets die primäre Technologie zur <a href="https://javaserverfaces.dev.java.net/nonav/docs/2.0/javadocs/javax/faces/view/ViewDeclarationLanguage.html" target="_blank" title="ViewDeclarationLanguage API">Beschreibung des Views</a>. Man kann natürlich JSP nutzen, wenn man den Sprung nicht durchführen möchte. Aber die Vorteile liegen eher bei Facelets!</p>
<pre class="brush: xml">
&lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot;
        &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&gt;

&lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;
      xmlns:ui=&amp;quot;http://java.sun.com/jsf/facelets&amp;quot;
      xmlns:f=&amp;quot;http://java.sun.com/jsf/core&amp;quot;
      xmlns:h=&amp;quot;http://java.sun.com/jsf/html&amp;quot;&gt;

&lt;h:head&gt;
  &lt;title&gt;JSF Demo&lt;/title&gt;
&lt;/h:head&gt;
&lt;h:body&gt;
  &lt;h1&gt;Register&lt;/h1&gt;
  &lt;h:form&gt;

    &lt;h:inputText id=&amp;quot;name&amp;quot; value=&amp;quot;#{fc.person.username}&amp;quot;&gt;
    &lt;/h:inputText&gt;
    &lt;h:commandButton value=&amp;quot;Check username&amp;quot; action=&amp;quot;#{fc.isUsernameValid}&amp;quot;&gt;
    	&lt;f:ajax execute=&amp;quot;name&amp;quot; render=&amp;quot;outIsUserValid&amp;quot; /&gt;
    &lt;/h:commandButton&gt;
    &lt;h:outputText id=&amp;quot;outIsUserValid&amp;quot; value=&amp;quot;#{fc.output}&amp;quot; /&gt;
  &lt;/h:form&gt;
  &lt;br /&gt;

  &lt;h:form&gt;
                &lt;!-- First select box to select the continent.... --&gt;
  		&lt;h:selectOneMenu value=&amp;quot;#{fc.continent}&amp;quot;&gt;
  			&lt;f:selectItems value=&amp;quot;#{fc.continents}&amp;quot; /&gt;
  			&lt;f:ajax render=&amp;quot;countrylist&amp;quot; /&gt;
  		&lt;/h:selectOneMenu&gt;

                &lt;!-- ...and depending of the selected continent, contains this
                      second select box the countries
                --&gt;
  		&lt;h:selectOneMenu value=&amp;quot;#{fc.country}&amp;quot; id=&amp;quot;countrylist&amp;quot;&gt;
  			&lt;f:selectItems value=&amp;quot;#{fc.countries}&amp;quot; /&gt;
  		&lt;/h:selectOneMenu&gt;
  &lt;/h:form&gt;
&lt;/h:body&gt;
&lt;/html&gt;
</pre>
<p>Mittels Facelets ist die Beschreibung der Views reiner XML/XHTML.<br />
In dem ersten Formular ist das Input-Feld, in dem der Nutzer überprüfen kann, ob sein Username schon vergeben ist. Die Überprüfung wird mittels Ajax durchgeführt. Hierfür ist der neue <a href="https://javaserverfaces.dev.java.net/nonav/docs/2.0/pdldocs/facelets/f/ajax.html" target="_blank" title="JSF2 API: Ajax Tag">&lt;f:ajax&gt;-Tag</a> zuständig. Beim betätigen des Buttons wird ein Ajax-Request verschickt, dieser beinhaltet die Werte aus den Felder in dem <em>execute</em>-Attribute. In unserem Fall aus dem Feld mit der ID <em>name</em>. Die Antwort wird, wie in dem <em>render</em>-Attribute definiert, in ID <em>outIsUserValid</em> eingefügt. Auf dem Server wird zur Verarbeitung die Methode FrontController.isUsernameValid() aufgerufen. Während des Aufrus ist FrontController#person mit den aktuellen Werten (hier: username) gesetzt.</p>
<p>In dem zweiten Formular gibt es zwei Select-Boxen. In dem einen kann ein Kontinent ausgewählt werden. Resultierend dazu, wird in der zweiten eine Liste von Ländern angezeigt. Diese Länder-Liste wird durch Ajax ermittelt.<br />
In der ersten Liste ist wieder ein &lt;f:ajax&gt;-Tag zu finden. Bei dem 1. Beispiel wurde der Request verschickt, wenn der Nutzer den Button drückt. D.h. in der Javascript-Welt, beim Click-Event, wird der Request verschickt. Das &lt;f:ajax&gt;-Tag wählt immer das passende Event aus, abhängig von der Komponente, in dem es verwendet wird.<br />
Bei Listen horcht es auf ein OnChange-Event. Natürlich kann man ein anderes Event festlegen, dafür gibt es das <em>event</em>-Attribut.<br />
D.h. also, sobald in der ersten Liste die Auswahl verändert wird, wird die zweite Liste aktualisiert (durch render=&#8221;countrylist&#8221;). Auf dem Server wird FrontController.getCountries() aufgerufen. In dem Kontext ist FrontController#continent belegt, da der Nutzer eine Auswahl in der 1.Liste durchgeführt hat. FrontController.getCountries() liefert nun nur ein Array von Ländern zurück. Die korrekte Verschachtelung in HTML-Elemente (option-Tag) übernimmt JSF!</p>
<p><strong>Fazit:</strong></p>
<ul>
<li>Mittels JSF 2.0 hat man weniger Konfigurationsaufwand</li>
<li>Durch den Einsatz von Facelets macht das Erstellen der HTML-Seiten wieder Spass. Hier kann man die vorhandenen HTML-Templates fast unverändert übernehmen&#8230;</li>
<li>Unproblematischer Javascript/Ajax-Einsatz, ohne es wirklich zu merken!</li>
<li>DI ohne Spring!</li>
</ul>
<p>Also der erste Eindruck hat überzeugt. Wenn man JSF-Fan war, wird man JSF-Fan weiter bleiben. Wenn nicht, könnte man es jetzt bestimmt werden <img src='http://my.center-of.info/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://my.center-of.info/2009/08/27/tutorial-jsf2-beipielanwendung/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spec 2.0: JSF 2 Überblick</title>
		<link>http://my.center-of.info/2009/08/26/jsf2overview/</link>
		<comments>http://my.center-of.info/2009/08/26/jsf2overview/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 20:52:45 +0000</pubDate>
		<dc:creator>Haf</dc:creator>
				<category><![CDATA[JEE]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[jsf2]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://my.center-of.info/?p=135</guid>
		<description><![CDATA[JSF ist ja nicht jedermanns Sache. Ich fand JSF 1.x auch mit den &#8220;Problemen&#8221; toll. Die Implementierung (Mojarra und MyFaces) hatten so manche Fehler und zusätzliche Funktionalitäten, welche in der Spec nicht definiert wurden. Aber im Großen und Ganzen ein gutes und solides Konzept. Leider jedoch ein Framework, was ein paar Jährchen und Trends hinter [...]]]></description>
			<content:encoded><![CDATA[<p>JSF ist ja nicht jedermanns Sache. Ich fand JSF 1.x auch mit den &#8220;Problemen&#8221; toll. Die Implementierung (<a href="https://javaserverfaces.dev.java.net/" target="_blank" title="Mojarra: JSF SUN RI">Mojarra</a> und <a href="http://myfaces.apache.org/" target="_blank" title="MyFaces Project">MyFaces</a>) hatten so manche Fehler und zusätzliche Funktionalitäten, welche in der Spec nicht definiert wurden. Aber im Großen und Ganzen ein gutes und solides Konzept.<br />
Leider jedoch ein Framework, was ein paar Jährchen und Trends hinter sich hat &#8211; JSF 1.1 (<a href="http://www.jcp.org/en/jsr/detail?id=127" target="_blank" title="JSR 127:JavaServer Faces">JSR 127</a>, 03.2001) und JSF 1.2 (<a href="http://www.jcp.org/en/jsr/detail?id=252" target="_blank" title="JSR 252:JavaServer Faces">JSR 252</a>, 05.2006). Seit 07.2009 gibt es nun das Final Release der JSF 2.0 Spezifikation (<a href="http://www.jcp.org/en/jsr/detail?id=314" target="_blank" title="JSR 314:JavaServer Faces">JSR 314</a>).<br />
<span id="more-135"></span><br />
Die <a href="https://javaserverfaces.dev.java.net/servlets/ProjectDocumentList?folderID=11662" target="_blank" title="Mojarra: 2.0.0-RC">RI von SUN</a> steht auch bald bereit und auch die Truppe um MyFaces hat einen <a href="http://matthiaswessendorf.wordpress.com/2008/08/29/myfaces-goes-jsf-20/" target="_blank" title="Matthias Wessendorf's Weblog: MyFaces goes JSF 2.0">JSF 2.0 Branch</a> erstellt. Spätestens jetzt sollte man einen Blick auf die Neuerungen und Verbesserungen, die mit 2.0 eingeführt werden, werfen.<br />
Möchte man sich nun mit JSF 2.0 auseinander setzen, könnte man sich die ersten Bücher besorgen, aber ob diese aktuell und praxistauglich sind, sei jedem überlassen.<br />
Die vielleicht komplette und aktuelle Information kriegt man zur Zeit, wenn man sich direkt die APIs anschaut und verschiedene Blogs verfolgt.<br />
Hier folgt erstmal eine unvollständige Liste von Informationsquellen (wird aktualisiert):</p>
<ul>
<li><a href="http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/" target="_blank" title="Andy Schwartz’s Weblog: What’s New in JSF 2?">Andy Schwartz Blogeintrag</a> Andy hat selbst eine Auflistung inklusive weitere Erklärung aufgeführt</li>
<li><a href="https://javaserverfaces.dev.java.net/users.html" target="_blank" title="Mojarra: Get Started">Mojarra: Get started</a></li>
<li><a href="https://javaserverfaces.dev.java.net/nonav/rlnotes/2.0.0/index.html" target="_blank" title="Mojarra 2.0.0 RC Release Notes Overview">Mojarra 2.0.0 Release Notes</a>: Mit den Verweisen zu den aktuellen APIs, TLDs etc</li>
</ul>
<p>Zu dieser Auflistung, die aktualisiert wird, folgen in dem Blog ein paar Beispiele zu speziellen Themen.</p>
<p>P.S.: In dem Block &#8220;Spec 2.0&#8243; folgen demnächst Beiträge zu Spezifikationen, Frameworks die nun in Version 2.0 erschienen sind.</p>
]]></content:encoded>
			<wfw:commentRss>http://my.center-of.info/2009/08/26/jsf2overview/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Commons-IO: DirectoryWalker</title>
		<link>http://my.center-of.info/2009/07/19/commons-io-directorywalker/</link>
		<comments>http://my.center-of.info/2009/07/19/commons-io-directorywalker/#comments</comments>
		<pubDate>Sun, 19 Jul 2009 19:43:27 +0000</pubDate>
		<dc:creator>Haf</dc:creator>
				<category><![CDATA[JEE]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[util]]></category>

		<guid isPermaLink="false">http://my.center-of.info/?p=132</guid>
		<description><![CDATA[Commons-IO bzw. allg. Apache Commons ist eine schöne Ansammlung von nützlichen Bibliotheken und Funktionen. Darunter ist auch Commons-IO zu finden. Daraus will ich heute eine spezielle Lösung vorstellen. Hat man folgendes Problem: Möchte man einen Ordner, inklusive dessen Unterordner, nach bestimmten Dateien suchen und dann diese vielleicht nach Last-Modified sortiert, bietet Commons-IO eine Lösung an. [...]]]></description>
			<content:encoded><![CDATA[<p>Commons-IO bzw. allg. <a href="http://commons.apache.org/" target="_blank" title="Apache Commons">Apache Commons</a> ist eine schöne Ansammlung von nützlichen Bibliotheken und Funktionen.<br />
Darunter ist auch Commons-IO zu finden. Daraus will ich heute eine spezielle Lösung vorstellen.<br />
Hat man folgendes Problem:<br />
Möchte man einen Ordner, inklusive dessen Unterordner, nach bestimmten Dateien suchen und dann diese vielleicht nach Last-Modified sortiert, bietet Commons-IO eine Lösung an.<br />
<span id="more-132"></span></p>
<p>Um den/die Ordner durchzulaufen existiert ein <a href="http://commons.apache.org/io/api-release/org/apache/commons/io/DirectoryWalker.html" target="_blank" title="Commons-IO API: DirectoryWalker">DirectoryWalker</a>.<br />
Um den abstrakten DirectoryWalker nutzen zu können könnte man z.B. eine folgende Implementierung nutzen:</p>
<pre class="brush: java">
public class TestDirectoryWalker extends DirectoryWalker {

	public TestDirectoryWalker(IOFileFilter dirFilter, IOFileFilter fileFilter, int depth) {
		super(dirFilter, fileFilter, depth);
	}

        /**
          * This method sets the start directory and starts the DirectoryWalker.
          */
	public List search(File startDir) throws IOException {

		List results = new ArrayList();
		walk(startDir, results);
		return results;
	}

	protected boolean handleDirectory(File directory, int depth, Collection results) {
		// return true, cause every sub directory is allowed
		return true;
	}

	protected void handleFile(File file, int depth, Collection results) {		

                // we want only the files with the name &quot;abc.txt&quot; in the
                // subdirectories. This files will be inserted in the given
                // result collection. This collection is the same as the
                // created List in search(File)
		String filename = file.getName();
		if(&quot;abc.txt&quot;.equalsIgnoreCase(filename))
			results.add(file);
	}
}
</pre>
<p>Wie man sehen kann, kann man innerhalb weniger Zeilen einen DirectoryWalker schreiben, der alle Unterordner durchgeht und alle Dateien mit dem Titel &#8220;abc.txt&#8221; liefert.<br />
Die Nutzung ist genauso simpel:</p>
<pre class="brush: java">
TestDirectoryWalker idw = new TestDirectoryWalker(DirectoryFileFilter.DIRECTORY, FileFilterUtils.suffixFileFilter(&quot;.txt&quot;), 3);

		String startDir = &quot;D:/Temp/.../blub&quot;;
		List files = null;
		try {
                        // search the directory for the wanted files
			files = idw.search(new File(startDir));
			System.out.println(&quot;Files: #&quot; + files.size());

                        // sort the resulting files using the LastModifiedFileComparator
			System.out.println(&quot;first file: &quot; + files.get(0));
			Collections.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);

			System.out.println(&quot;oldest file: &quot; + files.get(0));
		} catch (IOException e) {
			e.printStackTrace();
		}
</pre>
<p>Der Konstruktor TestDirectoryWalker(<a href="http://commons.apache.org/io/api-release/org/apache/commons/io/filefilter/IOFileFilter.html" target="_blank" title="Apache Commons-IO API: IOFileFilter">IOFileFilter</a>, <a href="http://commons.apache.org/io/api-release/org/apache/commons/io/filefilter/IOFileFilter.html" target="_blank" title="Apache Commons-IO API: IOFileFilter">IOFileFilter</a>, int) erwartet zwei Filter, einen für die Ordner und einen für die Dateien. Die <a href="http://commons.apache.org/io/api-release/org/apache/commons/io/filefilter/IOFileFilter.html" target="_blank" title="Apache Commons-IO API: IOFileFilter">Auswahl</a> ist umfangreich, ansonsten kann man auch seinen eigenen schreiben.</p>
<p>Als letztes ist vielleicht noch die Zeile</p>
<pre class="brush: java">
Collections.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
</pre>
<p>interessant. <a href="http://commons.apache.org/io/api-release/org/apache/commons/io/comparator/LastModifiedFileComparator.html" target="_blank" title="Apache Commons IO API: LastModifiedFileComparator">LastModifiedFileComparator</a> ist wie der Name schon andeutet, eine Klasse welches <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Comparator.html" target="_blank" title="J2SE API: Comparator">Comparator</a> implementiert bzgl. <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html#lastModified()" target="_blank" title="J2SE API: File#lastModified()">File.lastModified()</a>. Die Liste mit den gefundenen Dateien wird aufsteigend sortiert.</p>
<p>Innerhalb weniger Minuten kann man verschiedene Ordner nach speziellen Dateien suchen. Dank <a href="http://commons.apache.org/io/" target="_blank" title="Apache Commons IO">Apache Commons IO</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://my.center-of.info/2009/07/19/commons-io-directorywalker/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Java JMS MQ Beispiel</title>
		<link>http://my.center-of.info/2009/06/23/java-jms-mq-beispiel/</link>
		<comments>http://my.center-of.info/2009/06/23/java-jms-mq-beispiel/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 09:27:51 +0000</pubDate>
		<dc:creator>Haf</dc:creator>
				<category><![CDATA[JEE]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jms]]></category>
		<category><![CDATA[mq]]></category>

		<guid isPermaLink="false">http://my.center-of.info/?p=128</guid>
		<description><![CDATA[Vor einiger Zeit wurde MQ installiert. Nun folgt endlich ein Beispiel wie man in Java MQ ansprechen kann. Dabei wird JMS (Java Message Servic) ohne JNDI (Java Naming and Directory Interface) verwendet. Ein JNDI-Beispiel folgt in einem späteren Blog. Das Beispiel zeigt wie man mittels JMS eine MQ Nachricht verschicken und empfangen kann. Die Architektur [...]]]></description>
			<content:encoded><![CDATA[<p>Vor einiger Zeit wurde <a href="http://my.center-of.info/2008/10/28/mq-install-on-linux/" target="_blank">MQ installiert</a>. Nun folgt endlich ein Beispiel wie man in Java MQ ansprechen kann. Dabei wird JMS (Java Message Servic) ohne JNDI (Java Naming and Directory Interface) verwendet. Ein JNDI-Beispiel folgt in einem späteren Blog.<br />
<span id="more-128"></span></p>
<p>Das Beispiel zeigt wie man mittels JMS eine MQ Nachricht verschicken und empfangen kann.<br />
Die Architektur steht hier nicht im Vordergrund, das nur die MQ Kommunikation.</p>
<p>Für das Versenden von MQ Nachrichten ist ein MQQueueSender verantwortlich, entsprechendes gilt für das Empfangen (MQQueueReceiver).<br />
Da bei MQ mehrere Clients Nachrichten verschicken können und jedem Client nur seine Antworten interessieren, gibt es die Möglichkeit dem Receiver einen Filter (Selector) anzugeben. Mit diesem Selector werden dann nur die MQ Nachrichten geliefert (empfangen), welche die Kriterien erfüllen.<br />
Hier lohnt es sich (nur) Correlation und Message ID zu nutzen, da andere Eigenschaften zu langsam in der Filterung sind.<br />
Bei der Correlation ID muss noch das Präfix &#8216;ID:&#8217; angehangen werden, welches bei der Message ID schon automatisch vorhanden ist.</p>
<p>Nachfolgend ein kleines MQ JMS Beispiel</p>
<pre class="brush: java">
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;

import com.ibm.jms.JMSTextMessage;
import com.ibm.mq.jms.JMSC;
import com.ibm.mq.jms.MQQueue;
import com.ibm.mq.jms.MQQueueConnection;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import com.ibm.mq.jms.MQQueueReceiver;
import com.ibm.mq.jms.MQQueueSender;
import com.ibm.mq.jms.MQQueueSession;
import com.ibm.msg.client.wmq.v6.base.internal.MQC;

public class TestMQJMSPlain {

     public static void main(String[] args) {

         MQQueueConnectionFactory cf = new MQQueueConnectionFactory();

         try {

           cf.setHostName(&amp;quot;...&amp;quot;);
           cf.setPort(1415);
           cf.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
           cf.setQueueManager(&amp;quot;...&amp;quot;);
           cf.setChannel(&amp;quot;SYSTEM.DEF.SVRCONN&amp;quot;);
           String qIn = &amp;quot;...&amp;quot;;
           String qOut = &amp;quot;...&amp;quot;;

           MQQueueConnection connection = (MQQueueConnection) cf.createQueueConnection();
           // create a new Session, which is not transacted
           MQQueueSession session = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
           // create queues
           MQQueue queueRead = (MQQueue) session.createQueue(qIn);
           MQQueue queueWrite = (MQQueue) session.createQueue(qOut);
           // if the client on the other side is a non-jms client set this property
           queueWrite.setTargetClient(JMSC.MQJMS_CLIENT_NONJMS_MQ);

           // create a sender
           MQQueueSender sender =  (MQQueueSender) session.createSender(queueWrite);
           MQQueueReceiver receiver = null;      

           // create the message which will be sent over MQ
           JMSTextMessage message = (JMSTextMessage) session.createTextMessage(dat);
          // define the message type (not really necessary, depends from the client on the other side)
          message.setJMSType(MQC.MQFMT_STRING);
          // set a correlation ID
          message.setJMSCorrelationID(&amp;quot;MyIdSomethingElse&amp;quot; + System.currentTimeMillis());
          // set the replay queue
          message.setJMSReplyTo(queueRead);

          // lets start the connection
          connection.start();

          // send the JMS-Message
          sender.send(message);

          // create the selector to retrieve only the right response
          // the combination of message and correlation ID depends the individually defined constraints
          // it is wise to use the correlation and message ID for the selector, cause this are
          // faster as some other properties
          // Hint: the format for correlation ID is
          // JMSCorrelationID = &#039;ID:AF01CE....hex string...&#039;
          // the prefix &#039;ID&#039; is mandatory. However the message ID contains the fragment &#039;ID:&#039;
          String selector = &amp;quot;JMSCorrelationID = &#039;ID:&amp;quot; + dumpId2Hex(message.getJMSCorrelationIDAsBytes()) +
                                 &amp;quot;&#039; AND JMSMessageID = &#039;&amp;quot; + message.getJMSMessageID() + &amp;quot;&#039;&amp;quot;;

          // create a receiver with the defined selector
          receiver = (MQQueueReceiver) session.createReceiver(queueRead, selector);

          // receive the response (with match the filter in the selector). This call blocks max. 20000 ms
          Message receivedMessage = receiver.receive(20000);

          // check if message is received and a text message
          if (receivedMessage instanceof TextMessage) {
               // get the content...
              String replyString = ((TextMessage) receivedMessage).getText();
         }

         // close everything...
         sender.close();
         receiver.close();
         session.close();
         connection.close();		    

           }
	    catch (JMSException jmsex) {
	    	log.error(&amp;quot;JMSException&amp;quot;, jmsex);
	    }
	    catch (Exception ex) {
	    	log.error(&amp;quot;An other error occurred.&amp;quot;, ex);
	    }
     }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://my.center-of.info/2009/06/23/java-jms-mq-beispiel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cache method results with Ehcache and Spring</title>
		<link>http://my.center-of.info/2009/04/07/cache-method-results-with-ehcache-and-spring/</link>
		<comments>http://my.center-of.info/2009/04/07/cache-method-results-with-ehcache-and-spring/#comments</comments>
		<pubDate>Tue, 07 Apr 2009 11:25:03 +0000</pubDate>
		<dc:creator>Haf</dc:creator>
				<category><![CDATA[JEE]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://my.center-of.info/?p=121</guid>
		<description><![CDATA[Caching ist eins der Aspekte welches man nicht unbedingt direkt in der Businesslogik verankern möchte. Hierzu empfehlt es sich eine AOP-Lösung. Mit AOP kann die Funktionalität einer Cache-Realisierung genutzt werden. Eins der populärsten Cache-Provider ist Ehcache. In dem Umfeld von Spring kann man Ehcache folgendermaßen integrieren: Man nutzt das aus dem nicht mehr gewarteten spring-modules-Projekt [...]]]></description>
			<content:encoded><![CDATA[<p>Caching ist eins der Aspekte welches man nicht unbedingt direkt in der Businesslogik verankern möchte. Hierzu empfehlt es sich eine AOP-Lösung. Mit AOP kann die Funktionalität einer Cache-Realisierung genutzt werden. Eins der populärsten Cache-Provider ist <a title="Ehcache" href="http://ehcache.sourceforge.net/" target="_blank">Ehcache</a>.</p>
<p>In dem Umfeld von <a title="SpringSource: Spring Framework" href="http://www.springsource.org/" target="_blank">Spring</a> kann man Ehcache folgendermaßen integrieren:</p>
<p><span id="more-121"></span>Man nutzt das aus dem nicht mehr gewarteten <a title="Spring-Modules" href="https://springmodules.dev.java.net/" target="_blank">spring-modules</a>-Projekt das <a title="Spring-Modules: Cache" href="https://springmodules.dev.java.net/docs/reference/0.8/html/cache.html" target="_blank">cache</a>-Modul. Ja, spring-modules wird durch Spring-Extensions abgelöst, jedoch werden nicht alle Projekte übernommen. D.h. manche Unterprojekte (wohl auch Cache) werden nicht nach <a title="Spring: Extensions" href="http://www.springsource.org/extensions" target="_blank">Spring-Extensions</a> übernommen. Wo da der Sinn liegt, ist wohl nur den Betreibern klar.</p>
<p>Die aktuelle Version 0.9 findet man auch schon seit Monaten in keinem Maven Repository. Da bleibt nichts anderes übrig, als sich die Bibliothek (spring-modules-cache.jar) selbst in das lokale Repository zu installieren [1]</p>
<p>Für die Abhängigkeit: spring-modules-cache benötigt <a title="Maven Repository Browser: oro" href="http://mvnrepository.com/artifact/oro/oro" target="_blank">oro-2.0.8</a>.</p>
<p>Um ein Bean mit Cache-Funktionalität zu erweitern, stellt spring-modules-cache z.B. CacheProxyFactoryBean zur Verfügung um Advices für das Hinzufügen von Objekten (<a title="Doc Spring-Modules: Caching Advice" href="https://springmodules.dev.java.net/docs/reference/0.8/html/cache.html#cachingAdvice" target="_blank">caching advice</a>) und Löschen von Objekte (<a title="Doc Spring-Modules: Flushing Advice" href="https://springmodules.dev.java.net/docs/reference/0.8/html/cache.html#flushingAdvice" target="_blank">flushing advice</a>) aus dem Cache bereitzustellen.</p>
<pre class="brush: xml">
&lt;bean id=&quot;cacheProviderFacade&quot; class=&quot;org.springmodules.cache.provider.ehcache.EhCacheFacade&quot;&gt;
        &lt;property name=&quot;cacheManager&quot; ref=&quot;cacheManager&quot; /&gt;
    &lt;/bean&gt;

    &lt;bean id=&quot;cacheManager&quot; class=&quot;org.springframework.cache.ehcache.EhCacheManagerFactoryBean&quot;&gt;
        &lt;property name=&quot;configLocation&quot; value=&quot;classpath:ehcache.xml&quot; /&gt;
    &lt;/bean&gt;

    &lt;bean id=&quot;fCacheableService&quot; class=&quot;org.springmodules.cache.interceptor.proxy.CacheProxyFactoryBean&quot;&gt;
      &lt;property name=&quot;cacheProviderFacade&quot; ref=&quot;cacheProviderFacade&quot; /&gt;
      &lt;property name=&quot;cachingModels&quot;&gt;
        &lt;props&gt;
          &lt;prop key=&quot;getCodes*&quot;&gt;cacheName=fCache&lt;/prop&gt;
        &lt;/props&gt;
      &lt;/property&gt;
      &lt;property name=&quot;target&quot; ref=&quot;fService&quot; /&gt;

      &lt;!-- Set a qualifier to distinguish between the available FServices --&gt;
      &lt;qualifier value=&quot;fMain&quot;/&gt;
    &lt;/bean&gt;
</pre>
<p>Wie man in der Konfiguration sehen kann, werden nur die Methoden <strong>getCodes*</strong> in dem Bean<strong> fService</strong> ge-cached. Mit dem Qualifier <strong>fMain</strong> kann man beim <a title="Spring Reference: Autowired" href="http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-autowired-annotation" target="_blank">Autowiring</a> nun das richtige Bean injizieren, denn durch den CacheProxyFactoryBean gibt es zwei Beans vom gleichen Typ.</p>
<p>Mit wenig Konfiguration hat man jetzt in Spring Caching eingeführt. Dabei wurde der Source-Code gar nicht angefasst &#8211; wenn man vom dem nun notwendigen <a title="Spring Reference: Fine tuning Autowired" href="http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-autowired-annotation-qualifiers" target="_blank">@Qualifier</a> absieht.</p>
<p>Links:<br />
[1] Maven FAQ: <a title="Maven FAQ: Install 3th party library" href="http://maven.apache.org/general.html#importing-jars" target="_blank">Install 3th party library</a><br />
[2] Spring-Modules: <a title="Doc Spring-Modules: Cache" href="https://springmodules.dev.java.net/docs/reference/0.8/html/cache.html" target="_blank">Cache</a></p>
]]></content:encoded>
			<wfw:commentRss>http://my.center-of.info/2009/04/07/cache-method-results-with-ehcache-and-spring/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

