1 Reply Latest reply: May 2, 2010 12:46 AM by Andrew Rubinger RSS

Introduce built-in support for bean archives

Dan Allen Master

The JSR-299 specification (CDI) introduces the concept of a bean archive as a variant of several existing Java EE archives:

 

  • A library jar, EJB jar, application client jar or rar archive is a bean archive if it has a file named beans.xml in the META-INF directory.
  • The WEB-INF/classes directory of a war is a bean archive if there is a file named beans.xml in the WEB-INF directory of the war.
  • A directory in the JVM classpath is a bean archive if it has a file named beans.xml in the META-INF directory.

 

At the very minimum, every bean archive must have a beans.xml file. The file can be empty. Without the file, the archive ceases to be a bean archive.

 

Right now, adding beans.xml always requires the following manual step:

 

ShrinkWrap.create("test.jar", JavaArchive.class)
   .addManifestResource(new ByteArrayAsset(new byte[0]), "beans.xml");

 

The problems with this situation are:

 

  • beans.xml is not formally recognized as a standard descriptor like web.xml (WebArchive) and application.xml (EnterpriseArchive)
  • the developer must add beans.xml manually because there is no way to indicate the intention to create a bean archive (it's not recognized)

 

My first thought was to introduce the new container and archive specs for bean archives:

 

public interface BeanContainer<T extends Archive<T>> {
   T setBeansXml(String resourceName) throws IllegalArgumentException;
   ...and so on
}

public interface BeanArchive implements
   Archive<BeanArchive>,
   ManifestContainer<BeanArchive>,
   ClassContainer<BeanArchive>,
   LibraryContainer<BeanArchive> {}
 
public interface BeanWebArchive implements
   Archive<BeanWebArchive>,
   ManifestContainer<BeanWebArchive>,
   ClassContainer<BeanWebArchive>,
   LibraryContainer<BeanWebArchive>,
   WebArchive<BeanWebArchive> {}

 

This would turn the above archive creation code into:

 

ShrinkWrap.create("test.jar", BeanArchive.class);

 

or

 

ShrinkWrap.create("test.war", BeanWebArchive.class);

 

In both cases, an empty beans.xml would be added automatically by the implementation. The developer could provide a replacement/override using setBeansXml(...) if desired.

 

Should we move forward with this idea?

 

The downside to this approach is that we have to implement BeanArchive and BeanWebArchive, even though all we are doing is adding a descriptor to each (specializing it). Maybe that isn't such a problem. But I was intrigued by the idea in the thread about Re: ShrinkWrap - Descriptors about specializing an archive, essentially moving it into the DSL rather than by building on the spec interfaces.

 

ShrinkWrap.create("test.jar", JavaArchive.class).specializeAs(BeanArchive.class);

 

p.s. Whatever we decide, we should do the same for EjbArchive and PersistenceArchive so that there is built-in support for ejb-jar.xml and persistence.xml, respectively.