About software development for the enterprise. Focus on Java EE and more general Java platforms.
You'll read a lot about Conferences, Java User Groups, Java EE, Integration, AS7, WildFly, EAP and other technologies that hit my road.

Saturday, February 20, 2010

Eclipselink 1.2.0 JPA, Spring 2.5.6, MySQL 5.4, JTA and Oracle WebLogic 10.3.2.0

09:49 Saturday, February 20, 2010 Posted by Markus Eisele
, , , ,
I came across a nice post from viralpatel.net. They are showing how to implement a simple url-shortener called "shorty". Really nice. But the technology decision was not that awesome. I am ok with Hibernate. But Struts? No. Thanks :) That reminds me of good old times. And they are gone.

Let's modernize the software stack a bit. We give it a try with the help of:
- Oracle WebLogic 10.3.2.0
- EclipseLink 1.2.0 (1.2.0.v20091016-r5565)
- Spring 2.5.6
- MySQL 5.4
- Maven
- Eclipse

First approach was to migrate shorty completely to the new platform. After playing around a bit, I discovered some things to take care of running it on wls. Therefore I'll stick to the basic JTA/JPA/WLS parts and I am not going to re-implement the complete webtier. I am not using Spring 3.x here, because it still does not exist on ibiblio.org :)

Create your project with maven
First step is to have a simple project setup. Maven is the best place to start. Create a new maven project:

mvn archetype:create \
-DgroupId=my.example.com \
-DartifactId=shortywls \
-DarchetypeArtifactId=maven-archetype-webapp

Next is to update the dependencies. We basically need some Java EE 5 jars, spring and some web components. An explicit EclipseLink dependency is not needed, cause we are going to stick to the JPA 1.0. Using Wls 10.3.2.0 makes this your default JPA provider! Add the following lines to your pom.xml

<dependencies>
<dependency>
<groupId>javaee</groupId>
<artifactId>javaee-api</artifactId>
<version>5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>

We are missing a place where to put our java files. Change to your newly created project directory and add a src\main\java folder to it. Now you are ready to go. This is the point, where it is best to start developing in your favorite IDE. If you are using eclipse, let maven do the preparation.

maven eclipse:eclipse

After that, you only have to import the newly created project into Eclipse.

Setup your Weblogic domain
Before we actually start implementing, we have to configure our infrastructure a bit. First is to create your weblogic domain. Use whatever you like. I love to take advantage of the Configuration Wizard (win). Find it in the start menue or browse to %WLS_HOME%\wlserver_10.3\common\bin\config.exe If your have entered the basics, create the domain and fire it up. Next is to access the Weblogic Server Administration Console (http://localhost:7001/console). Make shure, you have your MySQL instance up an running and have a database and a user with all needed rights created prior to the next steps. Now browse to -Summary of Services -JDBC -JDBC Data Sources and choose "New".
Enter a Name and JNDI name for your new DataSource and choose MySQL as Database Type and the appropriate Driver. Click "Next" and choose the transaction options. Another "Next" click guids you to the connection properties. Enter your database name, hostname and port together with your username. A last "Next" click adds a "Test Configuration" to the button line on the top. Klick it and make shure, the Message says: "Connection test succeeded." After that, you have to restart your instance. Do this, even if the console tries to make you believe that this is not necessary.



If you are wondering, why we did not add either a dependency to the mysql-jconnector or a jar to the domain/server directory. This is quite simple. The Wls already ships with a mysql-connector-java-commercial-5.0.3-bin.jar. You can find it here %WLS_HOME%\wlserver_10.3\server\ext\jdbc\mysql.

configuring shortywls
Let's start over with JPA configuration. Add a persistence.xml to src\main\resources.
Insert the EclipseLink PersistenceProvider and your jta-data-source reference. If you like to know, what EclipseLink is doing also add the needed logging.level. Don't forget to tell EclipseLink about it's target server. In our case "WebLogic_10".

<persistence-unit name="shortyWeb" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>localJTA</jta-data-source>
<class>shorty.domain.Link</class>
<properties>
<property name="eclipselink.target-server" value="WebLogic_10" />
<property name="eclipselink.logging.level" value="FINEST" />
</properties>
</persistence-unit>

That's all. We are done with JPA :) The next bigger part is to do the basic configuration for spring. First step is to add the needed spring features to the web.xml located in src\main\webapp\WEB-INF. First is the place for your applicationContext.xml followed by the ContextLoaderListener and the Spring DispatcherServlet. Completed by the servlet mapping. Don't forget to add a shortyAppDispatcher-servlet.xml to your src\main\webapp\WEB-INF.

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>shortyAppDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>shortyAppDispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>

If this is done, you have to take a closer look at the specific spring configuration. Add the configured applicationContext.xml to src\main\webapp\WEB-INF. That's where all the magic happens. I'll focus on the JPA/JTA parts here. The rest is basic spring configuration, you can find a great documentation on the springsource website.

There are some Weblogic specific tweaks, you have to do. In terms of load-time-weaving you have to use the WebLogicLoadTimeWeaver.

<context:load-time-weaver
weaver-class="org.springframework.instrument.classloading.weblogic.WebLogicLoadTimeWeaver" />

The <tx:jta-transaction-manager /> does a self discovery of the transaction manager of the actuall server. Hence we are running on Wls this forces spring to use the org.springframework.transaction.jta.WebLogicJtaTransactionManager. The <tx:annotation-driven /> let you use the org.springframework.transaction.annotation.*'s

<tx:jta-transaction-manager />
<tx:annotation-driven
transaction-manager="transactionManager" />

If you have the jta transaction manager and the load-time-weaving in place, you need to add the jpaVendorAdapter. No Weblogic specific magic in here. Only the reference to the database platform and some debug information.

<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="databasePlatform"
value="org.eclipse.persistence.platform.database.MySQLPlatform" />
<property name="generateDdl" value="true" />
<property name="showSql" value="true" />
</bean>

Last bit to tie all parts together is the EntityManagerFactory. Spring JPA offers three ways of setting up JPA EntityManagerFactory. The only working solution here is the LocalContainerEntityManagerFactoryBean. If you try to use the LocalEntityManagerFactoryBean or the JNDI lookup, you will experience a "Error binding to externally managed transaction" Exception
It has a reference to the jpaVendorAdapter and the persistenceUnitName.

<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="persistenceUnitName" value="shortyWeb" />
</bean>

Implementing shortywls
Now we are done with configuration :) Switch back to Eclipse and do the implementation work.
You can basically stick to the viralpatel.net. Adapting spring, you need at least a dao which defines the transactional attributes to the methods.
Happy coding!