JSR-299 EG,<div><br></div><div>For a while now, the Seam 3 project has been working to solve a portability issue that prevents modules (i.e., extensions) from running on GlassFish (3.0 and 3.1) [1]. After much research, we&#39;ve determined that this isn&#39;t a problem that we have much control over. It&#39;s clear that there is an inconsistency in the way the JSR-299 specification is being interpreted with regard to extension loading.</div>


<div><br></div><div>The question is this. Does an extension have to be in an bean archive in order to be loaded?</div><div><br></div><div>Section 11.5 states:</div><div><br></div><div>&quot;An extension is a service provider of the service javax.enterprise.inject.spi.Extension declared in META-INF/services.&quot;</div>


<div><br></div><div>If one assumes that &quot;service provider&quot; refers to the term defined in the jar specification [2], then one would conclude that an extension does not have to be in a bean archive to be recognized (these are orthogonal concerns). However, the Java EE 6 reference implementation (GlassFish) does not honor this interpretation prior to version 3.1-b37, as indicated by [3].</div>


<div><br></div><div>Even with the recent fix to the reference implementation, there is a secondary interpretation problem:</div><div><br></div><div>Can an extension register a bean programmatically for a class that resides in another non-bean archive?</div>


<div><br></div><div>This question requires a short example.</div><div><br></div><div>Assume one archive, a.jar, has the following contents:</div><div><br></div><div>org/opentck/javaee/cdi/spi/beforebeandiscovery/BeanClassToRegister.class</div>


<div><br></div><div>A second archive, b.jar, has the following contents:</div><div><br></div><div>org/opentck/javaee/cdi/spi/beforebeandiscovery/AnotherBeanClassToRegister.class</div><div>org/opentck/javaee/cdi/spi/beforebeandiscovery/AnotherManualBeanRegistrationExtension.class</div>


<div>org/opentck/javaee/cdi/spi/beforebeandiscovery/ManualBeanRegistrationExtension.class</div><div>META-INF/services/javax.enterprise.inject.spi.Extension</div><div><br></div><div>AnotherBeanClassToRegister has an injection point of type BeanClassToRegister:</div>


<div><br></div><div>public class AnotherBeanClassToRegister {</div><div>   @Inject</div><div>   private BeanClassToRegister collaborator;<br>}</div><div><br></div><div>BeanClassToRegister and AnotherBeanClassToRegister are added as beans programmatically in respective extensions listed in the service provider descriptor:</div>


<div><br></div><div><div>public class ManualBeanRegistrationExtension implements Extension {</div><div></div></div><div><div><div>   public void registerBeans(@Observes BeforeBeanDiscovery event, BeanManager bm) {</div>
<div>      event.addAnnotatedType(bm.createAnnotatedType(BeanClassToRegister.class));</div><div>   }</div></div></div><div>}</div><div><br></div><div>public class AnotherManualBeanRegistrationExtension implements Extension {</div>


<div><div>   public void registerBeans(@Observes BeforeBeanDiscovery event, BeanManager bm) {</div><div>      event.addAnnotatedType(bm.createAnnotatedType(AnotherBeanClassToRegister.class));</div><div>   }</div></div><div>


}</div><div><br></div><div>The two libraries, a.jar and b.jar are bundled in a web archive, test.war</div><div><br></div><div>WEB-INF/lib/a.jar</div><div>WEB-INF/lib/b.jar</div><div>WEB-INF/beans.xml</div><div><br></div>

<div>
Deploying this archive to the reference implementation fails with an error message that the injection point from above cannot be satisfied. Clearly there is a visibility problem across bean archives in this case.</div><div>


<br></div><div>Adding META-INF/beans.xml to a.jar and removing the ManualBeanRegistrationExtension from b.jar resolves the issue in the reference implementation.</div><div><br></div><div>The fact that there is so much discussion around this issue has led me to the conclusion that it needs to be addressed at the specification level.</div>


<div><br></div><div>These scenarios have been prepared using Open TCK tests (based on Arquillian). [4]</div><div><br></div><div>-Dan</div><div><br></div><div>p.s. Thanks to Jason Porter for helping track down this issue and drafting the initial the Open TCK tests.</div>


<div><br></div><div>[1] <a href="https://issues.jboss.org/browse/SOLDER-47" target="_blank">https://issues.jboss.org/browse/SOLDER-47</a></div><div>[2] <a href="http://download.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider" target="_blank">http://download.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider</a></div>


<div>[3] <a href="http://java.net/jira/browse/GLASSFISH-14808" target="_blank">http://java.net/jira/browse/GLASSFISH-14808</a></div><div>[4] <a href="https://github.com/opentck/javaee_cdi/tree/master/src/test/java/org/opentck/javaee/cdi/spi/beforebeandiscovery" target="_blank">https://github.com/opentck/javaee_cdi/tree/master/src/test/java/org/opentck/javaee/cdi/spi/beforebeandiscovery</a></div>


<div><br>-- <br><div>Dan Allen</div>Principal Software Engineer, Red Hat | Author of Seam in Action<br>Registered Linux User #231597<br><br><a href="http://mojavelinux.com" target="_blank">http://mojavelinux.com</a><br><a href="http://mojavelinux.com/seaminaction" target="_blank">http://mojavelinux.com/seaminaction</a><br>


<a href="http://www.google.com/profiles/dan.j.allen" target="_blank">http://www.google.com/profiles/dan.j.allen</a><br>
</div>