Maven driven compile time ehnancement

#1

Hi,

   Just thought I'd share a small bit of Maven config to aid in enhancing persistent classes during compile time. Just add the following to your pom.xml:

 <build>
  <plugins>
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.2</version>
    <dependencies>
     <dependency>
      <groupId>com.objectdb</groupId>
      <artifactId>objectdb</artifactId>
      <version>${com.objectdb.version}</version>
      <scope>compile</scope>
     </dependency>    
    </dependencies>
    <executions>
     <execution>
      <phase>compile</phase>
      <goals>
       <goal>java</goal>
      </goals>
     </execution>
    </executions>
    <configuration>
     <mainClass>com.objectdb.Enhancer</mainClass>
     <!-- List of your packages -->
     <arguments>
      <argument>com.x.y.a.*</argument>
      <argument>com.x.y.b.*</argument>
     </arguments>
    </configuration>
   </plugin>

Then, in your output when performing a 'mvn clean compile' you should see something like the following (after the compile has completed):

[INFO] --- exec-maven-plugin:1.2:java (default) @ project-domain  ---
[ObjectDB 2.2.2 Enhancer]
4 persistable types have been enhanced:
  com.x.y.a.AB
  com.x.y.a.AC
  com.x.y.b.AA
  com.x.y.b.AZ

 

Hope somebody finds it useful. I searched around for it but couldn't find a maven centric way to handle it.

Cheers

#2

Thank you for this post. Integration of enhancement into Maven is certainly useful.

I could use your example to enhance a console application but it seems that applying it on a web application might require an additional action. Please try the following:

  • Download the tutorial web application Maven project.
  • Replace the pom.xml file with the attached file.
  • Run the project from the console - using mvn package jetty:run
  • The enhancement message is shown, but the Guest.class file in the generated Guestbook.war is not enhanced (you can see that the class file size has not been changed).

Any idea what is the problem?

 

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#3

For some reason, the example doesn't like 'guest.GuestListener'. I get the error:

[ObjectDB 2.2.2] Failed to generate dynamic type guest.GuestListener (error 361)

One small change - I explicitly set the class I wanted to enhance.

I attached the pom.xml you supplied with the minor change in it. I think I need some help figuring out the 361 error code however. I'm using OSX and it worked fine for me now.

This is the new output (just pasted the relevant part):

[ObjectDB 2.2.2 Enhancer]
1 persistable type has been enhanced:
    guest.Guest

Actually, your phase is a better choice than mine, as mine only does compile time - modified to actually deploy to repo!

 

#4

You are right. Here is the full stack trace. The exception is thrown because the GuestListener class depends on a missing type (ServletContextListener which is not available to the Enhancer).

com.objectdb.o.UserException: Failed to generate dynamic type guest.GuestListener
 at com.objectdb.o.MSG.d(MSG.java:74)
 at com.objectdb.o.ACL.e(ACL.java:185)
 at com.objectdb.o.BCL.loadClass(BCL.java:59)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
 at com.objectdb.o.SCM.w(SCM.java:451)
 at com.objectdb.o.JEW.aG(JEW.java:160)
 at com.objectdb.o.JEL.A(JEL.java:429)
 at com.objectdb.o.JEN.k(JEN.java:92)
 at com.objectdb.Enhancer.main(Enhancer.java:32)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:291)
 at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener
 at java.lang.ClassLoader.defineClass1(Native Method)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:466)
 at com.objectdb.o.ACL.e(ACL.java:174)
 ... 13 more
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContextListener
 at java.lang.ClassLoader.findClass(ClassLoader.java:359)
 at com.objectdb.o.ACL.loadClass(ACL.java:136)
 at com.objectdb.o.BCL.loadClass(BCL.java:63)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
 at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
 ... 17 more

Actually the message that I saw (regarding successful enhancement) was generated by the on the fly enhancement in the listener during run, and not by the Maven enhancement that failed.

Your solution solves the problem.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#5

Ahh ok yes that makes sense. I've seen the issue many times in other systems that do byte code enhancements missing the external dependencies.

I guess I should have stated (everything is better retrospectively) that my pom.xml was only targeting my domain classes project. With the domain class project, I also have "Entity Listeners" so I omit those packages, but I'm a bit of a fanatic when it comes to package naming, which made it easier.

Happy to help!


Post Reply

To post a reply and/or subscribe to update notifications - please login