Monthly Archives: March 2014

Java 8 default interface methods and JDK dynamic proxies


Java 8 added the ability to support default methods in interfaces.
That’s great for a lot of reasons and it works fine but what about
dynamic proxies? Are the default method skipped when needed? Are they
forwarded to the invocation handler?

Well JVM is well done and it is forwarded to the InvocationHandler. It
means your invocation handler invoke(proxy, method, args) method is
invoked when calling an interface method with a default….which
sounds logical since after all that’s an interface method.

When you use proxies to fully decorate an existing instance no issue,
if you call the default method your proxy will call the same method on
the delegate instance and if it should use the default it will….but
if you hack the proxy to implement it on the
fly without any delegate how to do?

In this case you know that if a method is a default one you need to
call the default implementation of the interface. Here are two issues:

  1. how to know a method is a default one?
  2. How to call the default implementation?

First issue is easy to solve, Java 8 added to its reflection API
java.lang.reflect.Method.isDefault(). Side note is you can check it in
previous java versions too backporting its implementation to an
utility method:

public boolean
isDefault() {
  return ((getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) ==
          Modifier.PUBLIC) &&
getDeclaringClass().isInterface();
}

The second issue is a bit more complex. If you call
method.invoke(proxy, args) you’ll loop in the proxy since the proxy
will try to invoke the real method which is the proxy one actually.

To workaround it you need to use java 7 new invoke API (MethodHandle).
The methods to have a look are the *Special ones which basically skip
the overriding checks.

Here how to do:

MethodHandles.lookup()
  .in(declaringClass)
  .unreflectSpecial(method, declaringClass)
  .bindTo(proxy)
  .invokeWithArguments(args);

First step is to get a lookup (kind of method handle factory), then
force the declaring class (default is caller class), unwrap the
java.lang.reflect.Method to a “special” MethodHandler and finally
invoke it on the proxy. Since it is “special” it will skip the
overriding done by the proxying and invoke the default implementation
:).

Here what the InvocationHandler finally looks like:

final
InvocationHandler handler = (proxy, method, args) -> {
if (method.isDefault())
{
final Class<?> declaringClass = method.getDeclaringClass();
return
MethodHandles.lookup()
.in(declaringClass)
.unreflectSpecial(method, declaringClass)
.bindTo(proxy)
.invokeWithArguments(args);
}

// proxy impl of not defaults methods
return null;
};

This opens several interesting doors. For instance with EJBs you could – if the spec goes this way – decorate an interface default method with @Asynchronous and return an AsyncResult just wrapping the other method. This way you get for all implementations asychronous calls for free from the implementations point of view.

Where it can go weird is if you can inject in parameters CDI beans or any injectable EE resources…then you don’t need classes anymore 😉

Want more content ? Keep up-to-date on my new blog

Or stay in touch on twitter @rmannibucau

Advertisements

Java 8 repeatable annotation: will it change JavaEE 8?


Not sure you noticed it since some changes are more important in java 8 but you can now repeat annotations. What does it mean?

Basically if we suppose you have this annotation:

Continue reading

java -jar my-app-in-tomee.jar


Starting Tomcat, TomEE or OpenEJB is quite simple, basically a single script to run….but a script. Sometimes in production you can’t use bash or something else and these scripts can be broken in the shell you have access to.

Another point can be the normalisation in the enterprise of runners: all java apps should be runnable with java -jar app.jar.

Well globally sometimes you need a jar to run TomEE. If you read my previous posts you know there are few solutions but nothing very simple.

That’s why TomEE Maven Plugin now supports an exec goal.

Continue reading

TomEE, CDI and LoginModule


JAAS is not the best security framework it exists but it is often enough for simple needs. Once you passed the setup (I’ll not detail it here) it is generally nice to use. However when writing a CDI app you need to do the bridge yourself.

You can hook it up with DeltaSpike BeanProvider but it is not that obvious/fluent.

Continue reading

Executable jar with TomEE and Tomcat Maven Plugin


Tomcat Maven plugin has a goal to allow you to create an executable jar: http://tomcat.apache.org/maven-plugin-2.0/tomcat7-maven-plugin/exec-war-mojo.html

It is nice but integrated with Tomcat so if you do JavaEE it doesn’t work…excepted if you use TomEE.

Continue reading

TomEE and ActiveMQ webconsole


ActiveMQ webconsole allows you to see broker information from a webapp. You can send and see messages for queues, topic…

However not sure it is due to a refactoring but last version doesn’t work well in TomEE. Looking further you realize there are some issues with activemq-webconsole packaging too (hope this will be fixed with next version).

However a simple workaround exists:

Continue reading

Test a particular CDI Extension with OpenEJB ApplicationComposer


OpenEJB ApplicationComposer is an old but very efficient way to test EE code. The idea is almost the same as with ShrinkWrap and Arquillian but with a big difference: it is performance oriented and embedded only. As a quick reminder to use the ApplicationComposer (either the JUnit runner or the abstract TestNG class) you just define a test class with a set of @Module methods declaring the in memory EE model (WebApp for web.xml, Beans for beans.xml, EjbJar for openejb-jar.xml, @Classes for scanned classes…) and standard @Test methods. Of course injections work in the test class. For instance:

Continue reading