Sunday, August 26, 2012

Arquillian, WebLogic with a HIbernate Enabled WebApp

For some upcoming work related applications, I decided to give  a try to Arquillian and WebLogic. Our constraint though was to ensure that we're using Hibernate, since we get very odd results when using EclipseLink in our WebLogic apps.

We're targetting WebLogic 12c for new applications, which ships with tools like SLF4J, Weld in our app server.  Lots of libraries are already loaded in your application as a result:

- SLF4J
- Javassist
- Jersey
- Jackson/Jettison

As a result of all of these libraries being available, you can get some very unexpected results trying to drop Hibernate in to your application.  In my case I was using it as a JPA implementation.  This is what my persistence.xml looks like as a result:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
    name="LOCALAPPS">
    org.hibernate.ejb.HibernatePersistence

      jdbc/LocalApps
      
          name="hibernate.hbm2ddl.auto" value="update"/>
          name="hibernate.transaction.jta.platform"
                value="org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform" />
      
   

In this scenario, I was using a MySQL database, where the connection was available as jdbc/LocalApps.  You can see on line 6 that I have set my JPA provider to Hibernate.  I ensured that Hibernate was in my project using the following dependency:


org.hibernate
hibernate-entitymanager
4.1.5.SP1
javassist
org.javassist




I had to remove javassist from Hibernate's dependency since it will conflict with Weld.  If you don't, you will receive deployment failures.  The javassist version deployed with WebLogic is binary compatible with Hibernate 4.1.5.SP1.  If you do not make this change, CDI injection will not work with your application.

Next up, we have to deal with an AST/ANTLR issue.  Hibernate uses AST for query object reading.  When you create a query "select p from Person p" it uses AST to read these tokens.  WebLogic's version is not binary compatible, so you cannot simply exclude the library.  You have to include it in your application.  In order to allow WebLogic core and your application to operate, you'll need the following weblogic.xml in your WAR file

1
2
3
4
5
    
        true
    
 
Now you should be able to deploy your Hibernate Web App on WebLogic 12c.  Now if you're like me, you want to start testing this application.  You'll want to define the following Deployment method in yoru arquillian test case


File[] libs = DependencyResolvers.use(MavenDependencyResolver.class)
                .loadEffectivePom("pom.xml")
                 .importAllDependencies()
                .resolveAsFiles();
        WebArchive wa = ShrinkWrap.create(WebArchive.class,"foo.war")
            .addClasses(BasicEntity.class,BasicEntityDAO.class)
            .addAsLibraries(libs)
            .addAsWebInfResource("web/weblogic.xml","weblogic.xml")
            .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
            .addAsResource("META-INF/persistence.xml","META-INF/persistence.xml")
            ;


The first four lines tell ShrinkWrap to gather all dependencies in the pom file - this will include hibernate as well. Similar to what we have to do to build the real deployment, we need to add a few extra items.  We'll need the weblogic.xml used to deploy the application, as well as the persistence.xml.  Note that you must use addAsResource and include the file location.  In order to ease my testing, I added the following to my build section of the pom file:


src/test/resources
src/main/resources
src/main/webapp/WEB-INF
web


This will add these locations to your test classpath.  This should simplify gathering files.  This could also be used if you are working with ArquillianDrone to test your web app.  Hopefully with these tips, you can simplify any pains when using Arquillian and WebLogic.

The source code for this tutorial can be found here: https://github.com/johnament/tad-arquillian-weblogic-hibernate

Happy Testing!