Friday, September 30, 2011

JavaOne 2011 schedule

JavaOne is next week and as usual I will be there.  I'm a bit busier than usual this year, but as always I'm more than happy to get together with anyone.  In fact it's my favorite part of JavaOne, so please do reach out.

Here's my speaking schedule:


Session ID: 23166
Session Title: Meet the Experts: EJB 3.2 Expert Group
Venue / Room: Hilton San Francisco - Imperial Ballroom A
Date and Time: 10/3/11, 21:00 - 21:45

Session ID: 25244
Session Title: EJB with Meta-annotations
Venue / Room: Parc 55 - Powell I/II-
Date and Time: 10/4/11, 17:30 - 18:15

Session ID: 23423
Session Title: The Road to Java EE 7: Is It All About the Cloud?
Venue / Room: Hilton San Francisco - Imperial Ballroom A
Date and Time: 10/5/11, 11:30 - 12:30

Session ID: 25209
Session Title: Fun with EJB 3.1 and OpenEJB
Venue / Room: Hilton San Francisco - Golden Gate 3/4/5
Date and Time: 10/5/11, 13:00 - 14:00

Session ID: 19941
Session Title: CDI Today and Tomorrow
Venue / Room: Hilton San Francisco - Imperial Ballroom A
Date and Time: 10/6/11, 12:30 - 13:30

Session ID: 23680
Session Title: Apache TomEE Java EE 6 Web Profile
Venue / Room: Hilton San Francisco - Golden Gate 3/4/5
Date and Time: 10/6/11, 11:00 - 12:00

Thursday, April 7, 2011

Final is my favorite Java keyword

Final is my favorite keyword and modifier in Java.  For fields, love it even more than private.  Think about it, you don't even need private on your field if it's final.  Not with a truly non-mutable data type at least, so collections and things of that nature excluded of course.

In fact I wish final was the default modifier for all my fields, variables, and parameters.  You should have to announce your intention to overwrite an already initialized object reference.  After years, I find it is a rarity.

There is nothing worse that digging through a large 500 line function and not being able to see what is changed and where.  Even more frustrating when you go to extract a method from said too-large codeblock and cannot do so easily because of the sprawled out variable declarations and initializations and the occasional "I like this variable name so I'll reuse the reference" laziness.

The trouble is it looks so terrible when used properly, which should be almost everywhere!  It looks pretty satisfying on fields, but over all parameters and variables it gets to be a little much.  It can actually make it harder to find the non-final object references.  And if you find one, was it intentional or just overlooked? Change it and find out I guess.

That is why one of my biggest wishes for the Java language is that final be the default and there to be a mutable or similar keyword for the handful of times you need it.  It would be an excellent aid to readers of your code, "watch out this thing is going to change." Compilers could even check to see if you have flagged something mutable and aren't actually mutating it.  That should be a compile error for variables and parameters, perhaps not for fields though.

Obviously we can't exactly do that ... not so directly.

We have some advantages now we didn't have when Java was created.  Annotations.  When Java was created there had to be long and deliberate thinking as to what the defaults should be.  Everyone would have to live with them and they'd last forever.  These days, however, a simple annotation or two on a Java source file could serve as a clean way to change such defaults in an obvious and documented way that can make the code in question far easier to read.  It would be syntactic sugar of course and that annotation and the defaults it specifies would compile away just as imports do.

A small bit of sugar with big payoff in ease and readability.

Friday, March 18, 2011

Reflection API gripes

java.lang.Method and java.lang.Constructor are strikingly close in concept. For all intents and purposes Constructors are little more than syntactic sugar. Yet there is no API acknowledgement of many their similarities.

Yes, they share some common interfaces and the same super class, but when you peal away the methods that are not accounted for by interfaces and superclasses, here's what you get:

java.lang.reflect.Constructor
public T newInstance(Object ... initargs)
public Annotation[][] getParameterAnnotations()
public Class[] getExceptionTypes()
public Class[] getParameterTypes()
public String toGenericString()
public Type[] getGenericExceptionTypes()
public Type[] getGenericParameterTypes()
public boolean isVarArgs()
java.lang.reflect.Method
public Object getDefaultValue()
public Object invoke(Object obj, Object... args)
public Class getReturnType()
public boolean isBridge()
public Type getGenericReturnType()
public Annotation[][] getParameterAnnotations()
public Class[] getExceptionTypes()
public Class[] getParameterTypes()
public String toGenericString()
public Type[] getGenericExceptionTypes()
public Type[] getGenericParameterTypes()
public boolean isVarArgs()
Of the methods, few are actually truly unique to that class type. Those would be the following methods

java.lang.reflect.Constructor
public T newInstance(Object ... initargs)
java.lang.reflect.Method
public Object getDefaultValue()
public Object invoke(Object obj, Object... args)
public Class getReturnType()
public boolean isBridge()
public Type getGenericReturnType()
A far smaller number, especially for Constructor. The remaining methods shared, but not accounted for in any superclass or interface, are:

Identical
public Annotation[][] getParameterAnnotations()
public Class[] getExceptionTypes()
public Class[] getParameterTypes()
public String toGenericString()
public Type[] getGenericExceptionTypes()
public Type[] getGenericParameterTypes()
public boolean isVarArgs()
These methods are just begging for an interface. Perhaps ParameterizedMember would be a good name?

Granted most Java development doesn't involve the reflection api, but those of us that do use it would really appreciate being thrown a bone. Especially with the growing amount of code and APIs that involve annotations. An interface similar to AnnotatedElement that can contain this critical getParameterAnnotations method would just be wonderful.

I'm quite certain there must have been some kind of debate. Likely one that ended in, "it's not really that important." Would love to hear from anyone involved.

I personally can't think of any downside to allowing us developers who deal with the guts of supporting annotation based APIs to get a little polymorphism in this are of the reflection API.

A bottle of my favorite rum to whomever can get this into Java 7.

Friday, October 1, 2010

EJB.next Connector/Bean API : JAX-RS and beyond

It isn't commonly known that MessageDrivenBeans (MDBs) are not directly tied to the Java Message Service (JMS). In fact, they are tied to the Java EE Connector Architecture. It's even less commonly known that MDBs are not necessarily asynchronous. It's really the Connector that drives the communication style.

Overall, it is a very cool model that does allow for some pretty impressive and standard extension to any compliant Java EE platform. It is, however, incredibly underused. With a few changes to the model, it could be made to support even things like JAX-RS. Let's break it down.

The touchpoints between the Connector and the MDB are the ActivationSpec/ActivationConfig and the MessageListener interface. Using a fictitious "Email" Connector idea, let's see how this looks.

EmailConsumer (MessageListener) interface

package org.superemail.connector;

// other imports...
    
public interface EmailConsumer {
    public void receiveEmail(Properties headers, String body);
}

EmailAccountInfo (ActivationSpec) class

package org.superemail.connector;
    
/**
 * This class is basically an old-style JavaBean with get/set for each property
 */
public class EmailAccountInfo implements javax.resource.spi.ActivationSpec {

    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public void validate() throws InvalidPropertyException {
    }
}

That's it for the Connector (aside from the Connector itself). I have left out a little detail on the ActivationSpec, we'll cover that later.

Now for the MDB's side of things. The MDB needs to implement the Connector's EmailConsumer interface and configure the Connector's EmailAccountInfo JavaBean which is done via the "activation-config" tag of the ejb-jar.xml or via @ActivationConfigProperty annotations in the @MessageDriven declaration.

@MessageDriven(activationConfig = 
        {@ActivationConfigProperty(
                propertyName = "address", 
                propertyValue = "dblevins@apache.org")
        })
public class EmailBean implements EmailConsumer {

    @PostConstruct
    public void init() {
    }

    public void receiveEmail(Properties headers, String body) {
        // do your thing!
    }
}

Done. Those are the basics. The Connector supplies a MessageListener interface and an ActivationConfig JavaBean, the MDB implements the interface and configures the JavaBean via the loosely-typed @ActivationConfigProperty.

There are a few things that prevent this model from reaching it's true potential:

  • Metadata is loosely typed in the bean code
  • Only class-level metadata is allowed, not method-level
  • Requiring an interface can limit expressiveness

Let's see how life might look if we eliminate the JavaBean and allow the Connector to instead supply an annotation.

package org.superemail.connector;
    
@Target(TYPE)
@Retention(RUNTIME)
@javax.resource.annotation.ActivationSpec
public @interface EmailAccountInfo {
    String address();
}

Side Note: The original javax.resource.spi.ActivationSpec interface has a 'validate()' method on it to validate the JavaBean. A clear update to that part of the API would be to instead use the Bean Validation API.

Which gives us a bean that might look like this:

@MessageDriven
@EmailAccountInfo(address = "dblevins@apache.org")
public static class EmailBean implements EmailConsumer {

    @PostConstruct
    public void init() {
    }

    public void receiveEmail(Properties headers, String body) {
        // do your thing!
    }
}

Now we're getting somewhere!

Ok, let's get rid of that message listener interface and image our Email Connector uses a very JAX-RS inspired API for consuming emails. If you know a little JAX-RS you'll see where I'm going with this.

@MessageDriven
@EmailAccountInfo(address = "dblevins@apache.org")
public static class EmailBean {

    @PostConstruct
    public void init() {
    }

    @Deliver @Header("Subject: {subject}")
    public void receiveEmail(@HeaderParam("subject") String subject, @Body String body) {
        // do your thing!
    }
}

Pretty neat, huh? Side note: For the rare few of you that speak Connector implementation, instead of giving your Resource Adapter a MessageEndpoint that is a proxy that only implements the MessageListener interface and the standard MessageEndpoint interface, the Container would instead give you an @LocalBean proxy that also implements MessageEndpoint. If you're thinking that an API like that would be great to use... imagine with the above changes you could make that API ... and use it in any compliant Java EE platform. Maybe even submit your own JSR if you came up with something great.

Truthfully speaking, it's the Connector who controls the lifecycle of the bean (MDB). The Connector API already allows for the Connector to say to the Container, "create me a bean" and "destroy this bean". So really, we don't need @MessageDriven anymore. Instead we can do this:

import javax.annotation.ManagedBean;

@ManagedBean
@EmailAccountInfo(address = "dblevins@apache.org")
public static class EmailBean {
 // ....
}

That's a little more modern and perhaps a bit clearer.

At this point, we have a generic API to hook arbitrary "Connectors" up to arbitrary "Beans" that are managed by a container. Were this the case when JAX-RS was created, they wouldn't have had to put so much effort into duplicating all the services that people who have managed beans expect: injection of resources, lifecycle callbacks, interceptors.

Summary: A few improvements to the expressiveness of the metadata passed between a Bean and its Connector could kick the MDB/Connector model into the mainstream as was the intention of the API from the beginning. New specifications could be created based on this model and be introduced incrementally as they are developed and needed.

The impact of fully opening up the Bean metadata to the Connector is quite deep and wide and likely not something that will scream at you immediately. Ask yourself, could something like the new EJB 3.1 @Schedule API have been done with a Connector/Bean model like this? To some extent probably it could. Certainly there already existed a few Quartz Connectors out there prior to the introduction of @Schedule.

Take a moment to daydream. What kind of Connectors could you create with this model?

Friday, September 24, 2010

Interceptor Advisor Pattern

Your standard CDI/EJB Interceptor example uses a logger as an around advice. Generally this gives you an interceptor that looks like so:

@Log
public class LoggingInterceptor {

    private java.util.logging.Logger logger =
            java.util.logging.Logger.getLogger("theLogger");

    @AroundInvoke
    public Object intercept(InvocationContext context) throws Exception {
        logger.info("" + context.getMethod().getName());
        return context.proceed();
    }
}

As of the Interceptors 1.1 spec, you can bind that to a bean via creating our own javax.interceptor.InterceptorBinding annotation. In our example, we've created one called @Log:

@InterceptorBinding
@Target(value = {ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
}

Now we just apply that to the bean as follows.

@Log
public class FooBean {

    public void somethingCommon(){
        //...
    }

    public void somethingImportant() {
        //...
    }

    public void somethingNoteworthy() {
        //...
    }
}

Great! Now we are done. Every time that bean is invoked, the LoggerInterceptor will issue a log message on info level. Aren't interceptors wonderful! End of story, right? Not quite.

Fundamentally, our example is still very contrived. Who wants to log everything on the same level?

Here is a little pattern that you can use to better advise your LoggerInterceptor around advice. First, we create a couple new annotations for log levels: @Fine and @Info

@Target(value = {ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Fine {
}

@Target(value = {ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Info {
}

Then we apply those to the bean...

@Log
public class FooBean {

    public void somethingCommon(){
        //...
    }

    @Info
    public void somethingImportant() {
        //...
    }

    @Fine
    public void somethingNoteworthy() {
        //...
    }
}

Now we alter our LoggerInterceptor to check for our new annotations and alter its behavior.

@Log
public class LoggingInterceptor {

    private java.util.logging.Logger logger =
            java.util.logging.Logger.getLogger("theLogger");

    @AroundInvoke
    public Object intercept(InvocationContext context) throws Exception {
        final Method method = context.getMethod();
        if (method.isAnnotationPresent(Info.class)) {
            return info(context);
        } else if (method.isAnnotationPresent(Fine.class)) {
            return fine(context);
        } else {
            return finest(context);
        }
    }

    public Object info(InvocationContext context) throws Exception {
        logger.info("" + context.getMethod().getName());
        return context.proceed();
    }

    public Object fine(InvocationContext context) throws Exception {
        logger.finest("" + context.getMethod().getName());
        return context.proceed();
    }

    public Object finest(InvocationContext context) throws Exception {
        logger.finest("" + context.getMethod().getName());
        return context.proceed();
    }
}

Done! Now we have a pattern to advise our interceptor!

This will totally work today. But this pattern is so simple and elegant what if we could support it right inside the container? Imagine how cool it would be if we could just do this in our interceptor and the container would just figure it out.

@Log
public class LoggingInterceptor {

    private java.util.logging.Logger logger =
            java.util.logging.Logger.getLogger("theLogger");

    @Info
    public Object info(InvocationContext context) throws Exception {
        logger.info("" + context.getMethod().getName());
        return context.proceed();
    }

    @Fine
    public Object fine(InvocationContext context) throws Exception {
        logger.finest("" + context.getMethod().getName());
        return context.proceed();
    }

    @AroundInvoke
    public Object finest(InvocationContext context) throws Exception {
        logger.finest("" + context.getMethod().getName());
        return context.proceed();
    }
}

Definitely something I plan to propose for the next round of specifications....

As always, comments welcome.

Tuesday, September 21, 2010

EJB.next Interceptor Improvements - Method signatures

Interceptors are great, but some parts of them are odd when applied practically. For as fundamentally reflective as interceptors are, it isn't possible to pass all interceptable calls through a single method, like so:

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.interceptor.AroundInvoke;
import javax.interceptor.AroundTimeout;
import javax.interceptor.InvocationContext;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;

public class StatsInterceptor {

    @PostConstruct
    @PreDestroy
    @PrePassivate
    @PostActivate
    @AroundInvoke
    @AroundTimeout
    public Object intercept(InvocationContext context) throws Exception {
        final long start = System.nanoTime();
        try {
            return context.proceed();
        } finally {
            final long nanos = System.nanoTime() - start;
            final long millis = MILLISECONDS.convert(nanos, NANOSECONDS);
            System.out.println("invoke time "+ millis +" milleseconds");
        }
    }
}

This looks very nice, but currently is not legal. The spec currently requires different formats for callback-based interception vs business-method-based interception. This sounds like a nice safe and conservative rule, but is it benefiting users? Not really. Let's see what we have to do to our interceptor to make it compliant.

First, callback intercept methods are not allowed to return anything and must have a void return type. The logic here is that since callbacks have no return value, interceptors should know this. So fine, let's work around that and just make a new method:

    @PostConstruct
    @PreDestroy
    @PrePassivate
    @PostActivate
    @AroundInvoke
    public void callback(InvocationContext context) throws Exception {
        intercept(context);
    }

Second, callback intercept methods are not allowed to throw any exceptions. Again the rationale is that callbacks aren't allowed to throw checked exceptions, so interceptors should be aware of that as well. The trick is we can't simply remove the 'throws Exception' clause without doing any extra work. The InvocationContext.proceed() method throws java.lang.Exception but we can't, so we are forced to take responsibility for it. If we just catch and ignore the exception all hell will break loose, so instead we should at least wrap it as a RuntimeException.

    @PostConstruct
    @PreDestroy
    @PrePassivate
    @PostActivate
    @AroundTimeout
    public void callback(InvocationContext context) {
        try {
            intercept(context);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

We've just made a mistake. Did you see it? If there are several interceptors in the chain and all of them wrap the exception like this, when an actual exception is thrown it will end up wrapped N times -- once per interceptor -- before finally reaching the container. Instead, we should at least check if the exception needs wrapping and hope that other interceptors do the same:

    @PostConstruct
    @PreDestroy
    @PrePassivate
    @PostActivate
    @AroundTimeout
    public void callback(InvocationContext context) {
        try {
            intercept(context);
        } catch (Exception e) {
            if (e instanceof RuntimeException) {
                throw (RuntimeException) e;
            } else{
                throw new RuntimeException(e);
            }
        }
    }

Now we're done. Summary: all of the above is boilerplate code you need in any well implemented callback-based interceptor.

What have we achieved? Not much.

In terms of user code, it doesn't help you any to have these restrictions. If you wanted special logic for callback-based interceptor methods you can easily put that annotation on a separate method.

In terms of container code, there's little gain as well. Ultimately, most containers use reflection to kick off the interceptor chain. The java.lang.reflect.Method.invoke() method returns Object and throws InvocationTargetException. Restricting users from returning Object and throwing Exception have no real impact on the container code. It's a callback. Ultimately all exceptions, checked or not, go into the log file and no further and return values are simply ignored.

Summary: The restriction on returning void and throwing Exception should be lifted. For backwards compatibility we can just say this former requirement is now optional and allow interceptor signatures of 'Object <method>(InvocationContext c) throws Exception' even if what is being intercepted is a callback.

Friday, July 16, 2010

@ApplicationException is evil... sort of

Historically EJB has frowned on RuntimeExceptions. Throwing them results in your transaction getting rolled back and your bean instance being immediately destroyed. You're welcome to try your transaction again ... just as long as you weren't keeping your data in your @Stateful session bean, cause, you know, the container just destroyed that... hope you didn't need it to retry your commit.

In EJB 3.0 the @ApplicationException type was added so that beans could throw RuntimeExceptions and not have their beans destroyed and have the choice to rollback any transaction in progress. Great! Only... how do you really use this for built-in exception types? XML you say? Yuk!

<ejb-jar>
    <assembly-descriptor>
        <application-exception>java.lang.RuntimeExceptions</application-exception>
    </assembly-descriptor>
</ejb-jar>

And is the above even a good idea? Definitely not! With something like that you're just asking for trouble. The bad part is that it effectively shuts off transaction exception handling for all beans in the entire application. Currently, though, this is your only option.

The problem is it is hard to use this annotation responsibly. It's often too bold and too difficult to take the hard line that a specific exception type is always fine to throw. It is completely lacking in pragmatism. There is no ability for developers to make a more refined choice.

Bottom line, it should be possible to specify how you would like a RuntimeException handled for a specific bean or method. Imagine @ApplicationException where modified like so:

@java.lang.annotation.Target({TYPE, METHOD})
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
public static @interface ApplicationException {
    Class value();

    boolean rollback() default false;
}
Now, we can do things a little more refined:
@LocalBean
public static class OrangeBean {

    @ApplicationException(RuntimeException.class)
    public void doSomething() {

    }

    public void doSomethingElse() {
        
    }
}

In the above, the OrangeBean doSomething method would be allowed to throw a RuntimeException without a transaction rollback or the bean instance being destroyed.

As well, the annotation could be placed on the class level. Say we have an @Stateful bean that wraps an EXTENDED PersistenceContext so that business logic could more easily be done elsewhere, perhaps by an @Stateless bean that uses Bean-Managed Transactions and wishes to batch process several transactions against the EXTENDED persistence context in a loop:

@Stateful
@ApplicationException(javax.persistence.PersistenceException.class)
@TransactionAttribute(MANDATORY)
public static class EntityManagerWrapper implements EntityManager {

    @PersistenceContext(type = EXTENDED)
    private EntityManager delegate;

    @Override
    public void persist(Object o) {
        delegate.persist(o);
    }

    @Override
    public  T merge(T t) {
        return delegate.merge(t);
    }

    @Override
    public void remove(Object o) {
        delegate.remove(o);
    }

    @Override
    public  T find(Class tClass, Object o) {
        return delegate.find(tClass, o);
    }

    //... and so on
}

The EntityManager API does not throw checked exceptions, only derivatives of javax.persistence.PersistenceException which is itself a RuntimeException. To wrap an EntityManager the bean also need the ability to throw javax.persistence.PersistenceException without causing its destruction and transaction rollback. In that vein, the bean is marked @TransactionAttribute(MANDATORY) so it isn't possible to use the bean without already having a transaction in progress, making it clear that transaction management is not it's responsibility.

In another example, say we would like to create a bean that wishes not be destroyed when a RuntimeException is thrown, but it would still like the transactions it starts (via @TransactionAttribute(REQUIRES_NEW)) to be rolled back should a RuntimeException occur.

@Stateful
@TransactionAttribute(REQUIRES_NEW)
@ApplicationException(value = RuntimeException.class, rollback = true)
public static class YellowBean {

    public void doSomething() {

    }

    public void doSomethingElse() {

    }
}

Naturally, to make this API work with more than one exception type per method or bean, we would of course need a new @ApplicationExceptions (note the plural) to group several @ApplicationException annotations -- for those that are not annotation-aware, you cannot use the same annotation twice on a type, method, field or any member.

@java.lang.annotation.Target({TYPE, METHOD})
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
public static @interface ApplicationExceptions {
    ApplicationException[] value() default {};
}
With that it would be possible to do all of the above for a few different exception types:
@Stateful
public static class RedBean {

    @ApplicationExceptions({
        @ApplicationException(NumberFormatException.class),
        @ApplicationException(ArrayIndexOutOfBoundsException.class),
        @ApplicationException(value = RuntimeException.class, rollback = true)
    })
    public void doSomething() {

    }

    public void doSomethingElse() {

    }
}

In the above the NumberFormatException and ArrayIndexOutOfBoundsException are considered OK and will not cause instance destruction or transaction rollback, however the '@ApplicationException(value = RuntimeException.class, rollback = true)' acts as a default clause of sorts and says all other RuntimeExceptions do not cause instance destruction, but do cause transaction rollback.

Conclusion: Being able to be more specific with @ApplicationException would be a great improvement. I definitely plan to propose it in EJB.next. If you like the idea, please leave a comment as numbers do greatly increase the likelihood of it being added. Other ideas on how to achieve a similar result more then welcome!