Archive

Archive for May, 2010

CDI, an overview – Part 2

May 31st, 2010 4 comments

In the previous part of CDI, we saw some injection, qualifiers and scope. Now, it’s time to browse through more advanced features.

Producers

Previous examples cannot resolve all our use-cases. Some of these include:

  • injection of random values
  • injection of context-dependent value
  • in general, places where the injection process cannot be narrowed down to a simple new()

These hint at a very well-known pattern, the factory. Factories are implemented in JSR-299 as producers.

Let’s take a simple example, the injection of a connection from a data source. The code that gets the connection either creates it with a direct connection to the database or retrieves it from a data source pool. In the latest case, the following code would fit:

public @interface FromDataSource {}

public class ConnectionProducer {

  @Produces @FromDataSource
  public Connection getConnection() throws Exception {

    Context ctx = new InitialContext();

    // Read the data source name from web.xml
    String name = ...

    DataSource ds = (DataSource) ctx.lookup(name);

    return ds.getConnection();
  }
}

Interceptors

With Java EE 6, you can harness the power of AOP without AOP. Like in the previous example, using interceptors is very straightforward. There are 3 steps. Let’s implement a simple timer, for benchmarking purposes.

The first step is the declaration of the interceptor. To do so, just use the @InterceptorBinding:

@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface Benchmarkable{}

The second step is the interceptor implementation. It uses the @Interceptor annotation, coupled with the previously defined one:

@Benchmarkable @Interceptor</pre>
public class BenchmarkInterceptor {

  @AroundInvoke
  public Object logPerformance(InvocationContext ic) throws Exception {

    long start = System.currentTimeMillis();

    Object value = ic.proceed();

    System.out.println(System.currentTimeMillis() - start);

    return value;
  }
}

Notice:

  • the method annotated with @AroundInvoke returns an Object
  • it uses a parameter of type InvocationContext

The last step is to declare such interceptors in WEB-INF/beans.xml because interceptors are deactivated by default.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
  <interceptors>
    <class>ch.frankel.blog.weld.BenchmarkInterceptor</class>
  </interceptors>
</beans>

The beans.xml also tells the container about how to order the interceptors in case they is more than one.

There are two other interceptor types, @PostConstruct and @AroundTimeout (for EJB).

Decorators

Decorators, guess what, implement the Decorator design pattern. They are very similar to interceptors with two interesting differences:

  • a decorator must implement the interface it is decorating (and yet can be abstract, so it does not have to implement the methods)
  • a decorator can have a reference to the object it decorates. It is done through injection

Like interceptors, they must be referenced in the beans.xml file in order to be activated. Let’s take a simple example and create an interface which contract is to return an HTML representation of an object:

public interface Htmlable {

 String toHtml();
}

Now I need a date class that knows its HTML representation. I know the design is quite bad but bear with me.

public class HtmlDate extends Date implements Htmlable {

  public String toHtml() {

    return toString();
  }
}

If I want a decorator that puts the HTML inside <strong> tags, here’s the way:

@Decorator
public class StrongDecorator implements Htmlable {

  @Inject @Delegate @Any
  private Htmlable html;

  public String toHtml() {

    return "<strong>" + html.toHtml() + "</strong>";
  }
}

Observers

CDI also implements the Observer design pattern, thus at last enabling simple event-driven development paradigm on the Java EE platform. The basis for it is the event type. An event type is a simple POJO.

The Observer is also a POJO: in order for a method of the Observer to be called when an event is fired, just add a parameter of the right event type and annotate it with @Observes:

public class EventObserverService {

  public void afterPostEvent(@Observes PostEvent event) {

    ... // Do what must be done
  }
}

On the other side, the event producer should have an attribute of type javax.enterprise.Event parameterized with the same event type. In order to fire the event, call event.fireEvent() with an event instance:

public class WeldServlet extends HttpServlet {

  @Inject
  private Event<PostEvent> event;

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    event.fire(new PostEvent());
  }
}

Now, when sending a POST request to the servlet, the afterPostEvent() method of the EventObserverService will be called.

Alternatives

In the previous article, I adressed the mock service with calling the setter and passing a newly created instance “by hand”. This is all fine and well in a unit testing case, but I also want to manage integration testing. The situation is thus the following:

  • there are two implementations of the same interface on the classpath
  • you can’t change the servlet code (for example, add a qualifier to the service attribute)

Given the deterministic nature of CDI, you should basically be toast. In fact, nothing could be further from the truth. Just use the @Alternative annotation and CDI will conveniently ignore the annotated class.

@Report(MAIL) @Alternative
public class MockMailReportServiceImpl implements ReportService {
  ...
 }

What’s the point then to create it in the first place? Remember the unused-till-then beans.xml from above. It will come to our help, since it accepts <alternative> tags. These tags activate the alternatives.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
  <alternatives>
    <class>ch.frankel.blog.weld.service.MockMailReportServiceImpl</class>
  </alternatives>
</beans>

As such, you could have two beans.xml:

  • a basically empty standard context
  • and another integration testing context full of alternatives

Platform

This article was written with GlassFish v3, which uses Weld v1.0.1, as a platform. Weld is CDI reference implementation, and also a part of the Seam framework.

I had no problems using the platform overall, yet, I couldn’t make alternatives, interceptors and decorators work. Strangely enough, all three must be configured in the WEB-INF/beans.xml. I do not know if I did something wrong or if there’s a bug in the current implementation though.

Conclusion

This 2-parts article only brushes at the surface of CDI. Nevertheless, IMHO, it looks very promising and I wish it much success.

To go further:

  • CDI, an overview – part 1
  • Commons annotations (JSR-250) page: Commons annotations has annotation for DI in Java (@Resource)
  • CDI (JSR-299) page: amazingly enough, CDI is about DI in Java EE
  • Weld’s documentation: Weld is CDI JBoss implementation and also the reference implementation
  • Article on the merits of JSR-299 compared to the merits of JSR-330
Categories: JEE Tags:

CDI, an overview – Part 1

May 22nd, 2010 9 comments

Introduction

I may be a Spring fanboy but I’m also convinced a technology should embrace standards. Although Spring is now a de facto standard, it is in competition with other products, like Google Guice for example. It makes my work as an architect harder since my craft is to devise the most perennial solutions: standards are my allies in achieving this goal.

CDI, formerly known as JSR 299, is an attempt at describing a true standard on Dependency Injection. What makes CDI appealing at first glance is that both SpringSource and Google took a seat in the specifications team. CDI is a part of the Java EE 6 stack, meaning an application running in a Java EE 6 compatible container can leverage CDI out-of-the-box.

Thus, for a Maven application, all that is required is to add the following dependency:

<dependency>
  <groupId>javax.enterprise</groupId>
  <artifactId>cdi-api</artifactId>
  <version>1.0-SP1</version>
  <scope>provided</scope>
</dependency>

The basics

How is it done? Let’s take a simple example. I still want to use a lighweight service layer: I just need a reference to such a service in my servlet. In order to do that, just add a reference to the service as an attribute and annotate it with @Inject:

public class WeldServlet extends HttpServlet {

  @Inject private HelloService helloService;

  ...
}

Note for Guice users: notice this is the same annotation, only in a standard package (javax.enterprise).

That’s all! No fancy XML configuration, no JNDI resource to use, no nothing. The only thing to do is to follow what I call the Highlander rule:

There can be only one.

This rule enforces that there must be one and only one class on the classpath that extends HelloService, thus fulfilling the interface contract. This is common sense: the injection must be deterministic and you can’t if you have more than one implementation to choose from.

Activation

In truth, if you just use the @Inject annotation, you probably will be faced by a NullPointerException. For CDI to activate, you’ll need to have a XML configuration file named beans.xml under WEB-INF for web applications or META-INF for jars. This file can be empty but is mandatory in order for CDI to bootstrap.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

Qualifiers

Yet, such condition is not met most of the time since you’ll probably have at least another mock implementation for your unit tests. A concept is missing somewhere: it is the qualifier. Qualifiers add a quality to injection so that the Highlander rule is enforced between all classes that meet all the injection qualifiers. Thus, one can add a distinguishing qualifier to the mock service to resolve our quandary. Let’s design such a qualifier:

  • to be considered a qualifier, it uses the @Qualifier annotation
  • since injection is done at runtime, the retention policy must be runtime
  • target will be type, since it’s the class itself that will be annotated

The result is the following:

@Qualifier
@Retention(RUNTIME)
@Target( { TYPE })
public @interface Mock {}

Just annotate your mock service with @Mock and presto, the injection will succeed again. We haven’t seen how to inject the mocked service, but please bear with me, it will be adressed later.

Setter injection

In fact, this situation should not really happen (at least if you use Maven), since your standard classpath and your testing classpath should be different. Moreover, your unit testing should IMHO not use injection. This would slightly change my servlet to be used both in standard context and unit testing context: I will need to be able to inject in the former case and to set manually in the latter. This is not a problem, since CDI also accepts setter injection like in the following snippet:

public class WeldServlet extends HttpServlet {

  private HelloService helloService;

  @Inject
  public void setHelloService(HelloService helloService) {

    this.helloService = helloService;
  }
  ...
}

More qualifiers

As we saw, the qualifier use-case from above was not a good example. A much better one would be the need for a servlet to report an error. There are much ways of reporting this: mail, log, SMS, etc. The service used to report would be dependent of the servlet, meaning all the services should be available on the classpath. Now, as we have seen previously with @Mock, each service would be annotated with @Mail, @Log, @SMS, etc. What we did not see is how to inject the right service. Nothing could be easier, just tell CDI that which service you need by providing the needed qualifier:

public class WeldServlet extends HttpServlet {

  @Inject @Mail private ReportService reportService;

  ...
}

When you do not define any qualifier, CDI will use one for you under the cover, @Default. That’s why just annotating the mock service with @Mock succeeded: the real service was annotated implicitly with @Default and that was enough to fulfill the Higlander rule.

Qualifiers with attributes

Using the previous method will likely lead to an exponential proliferation of qualifiers that contradict Java EE 6 goals of readibility and maintainability. CDI will still let you reach them goals with annotation members. Now, the classes are:

public enum ReportType {

  MAIL, SMS, LOG;    // Adding one more type here is easy
}

@Qualifier
@Retention(RUNTIME)
@Target( { TYPE, FIELD })
public @interface Report {
    ReportType value();
}

@Report(MAIL)
public class MailReportServiceImpl implements ReportService {...}

public class WeldServlet extends HttpServlet {

  @Inject @Report(MAIL)
  private ReportService reportService;
  ...
}

Creating another reporting service consists of creating the service implementation itself and adding a value to the enumeration.

Singletons

Traditionally, services are stateless and, as such, have little interest in being instantiated more than once: it’s a good practice to make them singletons. Frameworks such as Spring make container-managed beans singletons as a default. Singletons creation is a feature of CDI but beware that singletons should be explicitly marked as such:

@Singleton
public class HelloServiceImpl implements HelloService {
  ...
}

Scoped beans

Singletons are only a particular case of a scope. In Java EE, scopes are well-defined regarding web applications: application, session, request and page. CDI does not manage page scope and adds a conversation scope that is tied to JSF. Scope usage in CDI is similar as Spring: injected bean will be tied to the defined scope and its visibility restricted to that scope.

Information relative to settings and preferences could well take place in a session-scoped bean for instance. Just add the right scope annotation to this bean:

@SessionScoped
public class UserSettings implements Serializable {

  private static final long serialVersionUID = 1L;
  ...
}

At this point, you should probably able to adress 80% of your needs. The next article will tackle advanced subjects like producers and alternatives.

To go further:

  • Commons annotations (JSR-250) page: Commons annotations has annotation for DI in Java (@Resource)
  • CDI (JSR-299) page: amazingly enough, CDI is about DI in Java EE
  • Weld’s documentation: Weld is CDI JBoss implementation and also the reference implementation
  • Article on the merits of JSR-299 compared to the merits of JSR-330
Categories: JEE Tags:

Decrease your pages load time, one year later

May 17th, 2010 No comments

More than one year ago, I blogged about pages load time and Jawr. Since then, either my projects were intranet applications where load time was not an issue or we had no say in the tools used. So, I had no possibility to use any of the tools I found then. Now, I’m soon to be faced by an application that will be used by people outside our network and I definitely want the application to be as responsive as possible. Armed with my previous Yahoo best practices, I hunted on the web for tools that could help me enforce them.

One rule I hold in high esteem is: minimize the number of HTTP requests. I think this rule has the most impact since browsers only send at most 2 HTTP requests at a time. Let’s take a classical example. Buttons play a big part in many applications and most of the time, you put an icon on them in order to tie them to the action in the user’s mind. This is simply done like so:

<button><img src="path/to/my/image" />Label</button>

This means that any screen that display more than one button type has the potential to be slow. One way to dramatically decrease the number of requests is to aggregate all the images in one and use CSS background images. The latter is available since the first version of CSS, just specify the background-image attribute to display the image behind an element . This usage is called CSS Sprites. The code now looks like:

<button class="update">Label</button>
button.update {
  background-image: url('path/to/my/image');
  background-repeat: no-repeat;
}

The astute reader will have remarked that the previous code has the same effect as the <img> in the <button>. The real usage is to use only the portion of the master image that we want, somehting akin to that:

button.update {
  background: transparent url('path/to/my/aggregate') -50px -50px no-repeat;
}

To aggregate the master image requires the right image tool. To compute the portion we want for each button is a pain in the butt (to speak politely).

Luckily, my old friend Jawr has the right feature to help me. Since version 3.2, it includes SmartSprites, a product that just does all aggregating and computing for me. How does that work? Just by putting some comments in your CSS:

  • to declare how the master(s) image(s) will be constructed
  • to tell which sprite will take part in which master image
/** sprite: master-sprite-gif; sprite-image: url('../img/master-sprite.gif'); sprite-layout: vertical */

button.one {
  background-image: url('../img/certificate_preferences.gif'); /** sprite-ref: master-sprite-gif; */
}

button.two {
  background-image: url('../img/inbox_into.gif'); /** sprite-ref: master-sprite-gif; */
}

button.three {
  background-image: url('../img/mail_forward.gif'); /** sprite-ref: master-sprite-gif; */
}

The previous CSS is an example by which all three GIFs will be found at runtime under ../img/master-sprite.gif. If you look at the generated CSS, it will have the following look:

button.one{background-image:url('../cb3648025844/img/master-sprite.gif');background-position:left -0px;}
button.two{background-image:url('../cb3648025844/img/master-sprite.gif');background-position:left -48px;}
button.three{background-image:url('../cb3648025844/img/master-sprite.gif');background-position:left -96px;}

Of course, the real generated CSS will have been concatenated and minified (see below).

Note: I’m not a GIF expert but I suspect original GIFs should have similar color tables, otherwise, the aggregated GIF will look really strange.

However, Jawr also provides some very interesting features, both old and new:

  • minification, for both CSS and JavaScript. You can also choose the minifying engine (embedded, JSMin or YUI Compressor). The latter is even able to obfuscate your source, thus even making your JS even lighter in the process
  • license inclusion, so that even minified sources can display their license
  • runtime GZip compression if the client browser supports it
  • HTTP header management so that requests for the same resources (beside the first) will be answered by a HTTP 304 – Not Modified code, thus avoiding unnecessary network traffic
  • i18n management in order to use Java standard properties files for internationalized messages in your JavaScript
  • JavaScript to use Jawr without taglibs in plain HTML pages (though it is not recommended since it adds a script to the page, thus another HTTP request)
  • possibility of extension, with new pre- and post- processors
  • ability to switch between development mode (no modification for resources) and production (virtual resources served by Jawr)
  • bundle preprocessing, so that the processing is not done at startup but instead at build time: this can be done either by calling an Ant task or by configuring a Maven plugin
  • for truly engaged application server administrators, support for JMX

During the last year, it seems Jawr has gained some nice upgrades. I don’t know how many people truly use it but I think it deserves some interest when you need to optimize performance on the page loading time front.

You can download the sources for this article in Eclipse/Maven format here.

To go further:

Categories: JEE Tags:

The power of proxies in Java

May 10th, 2010 1 comment

In this article, I’ll show you the path that leads to true Java power, the use of proxies.

They are everywhere but only a handful of people know about them. Hibernate for lazy loading entities, Spring for AOP, LambdaJ for DSL, only to name a few: they all use their hidden magic. What are they? They are… Java’s dynamic proxies.

Everyone knows about the GOF Proxy design pattern:

Allows for object level access control by acting as a pass through entity or a placeholder object.

Likewise, in Java, a dynamic proxy is an instance that acts as a pass through to the real object. This powerful pattern let you change the real behaviour from a caller point of view since method calls can be intercepted by the proxy.

Pure Java proxies

Pure Java proxies have some interesting properties:

  • They are based on runtime implementations of interfaces
  • They are public, final and not abstract
  • They extend java.lang.reflect.Proxy

In Java, the proxy itself is not as important as the proxy’s behaviour. The latter is done in an implementation of java.lang.reflect.InvocationHandler. It has only a single method to implement:

public Object invoke(Object proxy, Method method, Object[] args)
  • proxy: the proxy instance that the method was invoked on
  • method: the Method instance corresponding to the interface method invoked on the proxy instance. The declaring class of the Method object will be the interface that the method was declared in, which may be a superinterface of the proxy interface that the proxy class inherits the method through
  • args: an array of objects containing the values of the arguments passed in the method invocation on the proxy instance, or null if interface method takes no arguments. Arguments of primitive types are wrapped in instances of the appropriate primitive wrapper class, such as java.lang.Integer or java.lang.Boolean

Let’s take a simple example: suppose we want a List that can’t be added elements to it. The first step is to create the invocation handler:


public class NoOpAddInvocationHandler implements InvocationHandler {

  private final List proxied;

  public NoOpAddInvocationHandler(List proxied) {

    this.proxied = proxied;
  }

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    if (method.getName().startsWith("add")) {

      return false;
    }

    return method.invoke(proxied, args);
  }
}

The invoke method will intercept method calls and do nothing if the method starts with “add”. Otherwise, it will the call pass to the real proxied object. This is a very crude example but is enough to let us understand the magic behind.

Notice that in case you want your method call to pass through, you need to call the method on the real object. For this, you’ll need a reference to the latter, something the invoke method does not provide. That’s why in most cases, it’s a good idea to pass it to the constructor and store it as an attribute.

Note: under no circumstances should you call the method on the proxy itself since it will be intercepted again by the invocation handler and you will be faced with a StackOverflowError.

To create the proxy itself:


List proxy = (List) Proxy.newProxyInstance(
  NoOpAddInvocationHandlerTest.class.getClassLoader(),
  new Class[] { List.class },
  new NoOpAddInvocationHandler(list));

The newProxyInstance method takes 3 arguments:

  • the class loader
  • an array of interfaces that will be implemented by the proxy
  • the power behind the throne in the form of the invocation handler

Now, if you try to add elements to the proxy by calling any add methods, it won’t have any effect.

CGLib proxies

Java proxies are runtime implementations of interfaces. Objects do not necessarily implement interfaces, and collections of objects do not necessarily share the same interfaces. Confronted with such needs, Java proxies fail to provide an answser.

Here begins the realm of CGLib. CGlib is a third-party framework, based on bytecode manipulation provided by ASM that can help with the previous limitations. A word of advice first, CGLib’s documentation is not on par with its features: there’s no tutorial nor documentation. A handful of JavaDocs is all you can count on. This said CGLib waives many limitations enforced by pure Java proxies:

  • you are not required to implement interfaces
  • you can extend a class

For example, since Hibernate entities are POJO, Java proxies cannot be used in lazy-loading; CGLib proxies can.

There are matches between pure Java proxies and CGLib proxies: where you use Proxy, you use net.sf.cglib.proxy.Enhancer class, where you use InvocationHandler, you use net.sf.cglib.proxy.Callback. The two main differences is that Enhancer has a public constructor and Callback cannot be used as such but only through one of its subinterfaces:

  • Dispatcher: Dispatching Enhancer callback
  • FixedValue: Enhancer callback that simply returns the value to return from the proxied method
  • LazyLoader: Lazy-loading Enhancer callback
  • MethodInterceptor: General-purpose Enhancer callback which provides for “around advice”
  • NoOp: Methods using this Enhancer callback will delegate directly to the default (super) implementation in the base class

As an introductory example, let’s create a proxy that returns the same value for hash code whatever the real object behind. The feature looks like a MethodInterceptor, so let’s implement it as such:


public class HashCodeAlwaysZeroMethodInterceptor implements MethodInterceptor {

  public Object intercept(Object object, Method method, Object[] args,
    MethodProxy methodProxy) throws Throwable {

    if ("hashCode".equals(method.getName())) {

      return 0;
    }

    return methodProxy.invokeSuper(object, args);
  }
}

Looks awfully similar to a Java invocation handler, doesn’t it? Now, in order to create the proxy itself:


Object proxy = Enhancer.create(
  Object.class,
  new HashCodeAlwaysZeroMethodInterceptor());

Likewise, the proxy creation isn’t suprising. The real differences are:

  • there’s no interface involved in the process
  • the proxy creation process also creates the proxied object. There’s no clear cut between proxy and proxied from the caller point of view
  • thus, the callback method can provide the proxied object and there’s no need to create and store it in your own code

Conclusion

This article only brushed the surface of what can be done with proxies. Anyway, I hope it let you see that Java has some interesting features and points of extension, whether out-of-the-box or coming from some third-party framework

You can find the sources for this article in Eclipse/Maven format here.

To go further:

Categories: Java Tags:

Chicken and egg problem with Spring and Vaadin

May 3rd, 2010 3 comments

The more I dive into Vaadin, the more I love it: isolation from dirty plumbing, rich components, integration with portlets, Vaadin has it all.

Anyway, the more you explore a technology, the bigger the chances you fall down the proverbial rabbit hole. I found one just yesterday and came up with a solution. The problem is the following: in Vaadin, application objects are tied to the session. Since I’m a Spring fanboy, it does make sense to use Spring to wire all my dependencies. As such, I scoped all application-related beans (application, windows, buttons, resources, …) with session like so:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/aop

    http://www.springframework.org/schema/aop/spring-aop.xsd">

  <context:annotation-config />

  <bean id="application" scope="session">
  <aop:scoped-proxy />
...
</beans>

This works nicely, until you happen to use DI to wire further. By wire further, I mean wiring windows into application, button into windows and then resources (icons) into buttons. It is the last  step that cause a circular dependency. Icon resources are implemented in Vaadin by com.vaadin.terminal.ClassResource. This class has two constructors that both needs an application instance.

The dependency cycle is thus: application -> window -> button -> resource -> application. Spring don’t like it and protests energically to it by throwing an exception which is labeled like so Requested bean is currently in creation: Is there an unresolvable circular reference?

. I think, in this case, that the design of the ClassResource is not adapted. That’s whyI designed a class aligned with Spring deferred instantiation: since the application is session-scoped, Spring uses a proxy that defers instantation from application start (Spring normal behaviour) to session use. The point is to implement the ApplicationResource interface, which needs an interface, but to set application only when needed:

public class DeferredClassResource implements ApplicationResource {

  private static final long serialVersionUID = 1L;
  private int bufferSize = 0;
  private long cacheTime = DEFAULT_CACHETIME;
  private Class<?> associatedClass;
  private final String resourceName;
  private Application application;

  public DeferredClassResource(String resourceName) {

    if (resourceName == null) {

      throw new IllegalArgumentException("Resource name cannot be null");
    }

    this.resourceName = resourceName;
  }

  public DeferredClassResource(Class<?> associatedClass, String resourceName) {

    this(resourceName);

    if (associatedClass == null) {

      throw new IllegalArgumentException("Associated class cannot be null");
    }

    this.associatedClass = associatedClass;
  }

... // standard getters

  @Override
  public String getFilename() {

    int index = 0;

    int next = 0;

    while ((next = resourceName.indexOf('/', index)) > 0
      && next + 1 < resourceName.length()) {
      index = next + 1;
    }

    return resourceName.substring(index);
  }

  @Override
  public DownloadStream getStream() {

    final DownloadStream ds = new DownloadStream(associatedClass
      .getResourceAsStream(resourceName), getMIMEType(),
      getFilename());

    ds.setBufferSize(getBufferSize());

    ds.setCacheTime(cacheTime);

    return ds;
  }

  @Override
  public String getMIMEType() {

    return FileTypeResolver.getMIMEType(resourceName);
  }

  public void setApplication(Application application) {

    if (this.application == application) {

      return;
    }

    if (this.application != null) {

      throw new IllegalStateException("Application is already set for this resource");
    }

    this.application = application;

    associatedClass = application.getClass();

    application.addResource(this);
  }
}

DeferredClassResource is just a copy of ClassResource, but with adaptations that let the application be set later, not only in constructors. My problem is solved, I just need to let application know my resources so it can call setApplication(this) in a @PostConstruct annotated method.

Categories: JEE Tags: ,