Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
67 lines (49 sloc) 3.64 KB

helloworld-classfiletransformer: Applying ClassTransformers to your Jakarta EE archive

This is a WAR based application showing you how Wildfly let you apply a ClassTransformer to the classes in your enterprise archive.

It consists of a server component and a client component: * The server component is a simple @Stateless session EJB called HelloBean, which exposes a SOAP based view * The client component is a simple Java application that makes a call to the EJB through it’s Web service interface

All code is co-bundled in this projects' WAR src directory.

About the code

This project is a Web ARchive (WAR) project. It’s src folder contains three packages: * hello.client : this is where you find the SOAP based Java application client * hello.server.ejb : this is where you find the EJB that exposes a SOAP based view * hello.server.transformation : this is where you find the bytecode manipulation code

Note the file: src/main/webapp/META-INF/jboss-deployment-structure.xml. This is where we register a Java ClassFileTransformer. A ClassFileTransformer is a class that has a transform method that receives a class’s bytecode as a byte array input and then produces the class’s new bytecode. If the transformer doesn’t want to modify the class received, then it simply returns the input array directly. If, however, it want’s to transform it, it does so by means of cglib, javaassist, etc. This example demonstrates bytecode manipulation using Javassist.

It is the EJB’s implementation class, HelloBean, that is modified in this example. The modification is really simple: it simply injects logging statements before and after the sayHello() method. But Javaassist can do much more - check out the relevant documentation for Javassist. Or choose another bytecode generation library. The choice is yours - Wildfly doesn’t care what you choose.

You could achieve the same effect using EJB interceptors or CDI interceptors. They are standard and would normally be the recommended way to go about "around" behavior. But Jakarta EE interceptors are not as powerful as bytecode manipulation can be: with bytecode manipulation you can easily advice unmanaged classes (including static member methods etc), "add/remove" interfaces, fields, methods and so on. And you can even advice code that is a third party dependency to your application (say Apache Commons library code).

Deploy the WAR

  • Start WildFly 10.1.0.Final (or newer)

  • mvn clean install wildfly:deploy

Run the SOAP client

  • mvn compile exec:java

Inspect the server log

Note that a single EJB was installed: HelloBean. It exposes a SOAP based interface, which is used by the client application.

Upon deployment you should see something like: "Instrumenting hello.server.ejb.HelloBean" and "Successfully instrumented hello.server.ejb.HelloBean". That is the example class transformer that tells you it has instrumented the HelloBean EJB.

Upon calling the EJB’s web service endpoint you should see something like: "INTERCEPTED MethodInvocation". One line before the method invocation. And one line after the method invocation.

Do make sure to verify that these lines hasn’t just been printed by the EJB’s sayHello() method.

And then check out the class "HelloByteCodeManipulator" which do the manipulation on behalf of the class transformer.

Finally: note that the transformer is registered in the WAR' archives META-INF/jboss-deployment-structure.xml file.

/Enjoy what is otherwise normally only performed by advanced Java Agents.

You can’t perform that action at this time.