History of Embedded JBoss
Why special integration with Tomcat?
JBoss Embedded predecessor E-EJB3 used to be bootstrappable within a war itself with no specific tomcat code. Why did we change this?
In its previous incarnation of Embedded JBoss, Embedded EJB3, we required you to reset the initial context environment to be able to use it. This created some ugly code both within user applications and the Embedded EJB3 codebase. We wanted user apps, the kernel and JBoss codebase to be isolated from these problems.
So, the new integration replaces Tomcat's JNDI implementation with JBoss's. Why? Tomcat's JNDI implementation can not cope with the way JBoss uses JNDI ObjectFactory and References. This is a bug in their implementation. I could not find a way to extended/override Tomcat's "java:comp" namespace so that EJB containers could have their own ENC and not be forced to define a "javaa:comp.ejb3" namespace. Another problem is that the "java:" namespace in Tomcat JNDI is read-only. A number of JBoss services use the "java:" namespace to register themselves with (TM, local JMS connection factory, etc...). Finally, Tomcat creates an InitialContext per web application and requires you to provide resource links to be able to see any globally defined things. Many JBoss components (liked EJB containers) depend on looking up the TransactionManager and security contexts in JNDI. I did not want to require the user to specify ResourceLinks for each and every WAR deployment they wanted to run. So all these problems led me to believe that I had to replace Tomcat's JNDI implementation with JBoss's.
Another problem was URL handling. The VFS included with Embedded JBoss uses its own URL protocol. Tomcat hardcoded its own, unextendable URL handler, so the placement of the Embedded Listener is important in the configuration.
1st commit 1/5/2007
Had to create my own JMXKernel bean
setups up JBoss URL Handlers. This should probably be moved out of this class
creates an MBean server by inlining the code that javax.management.MBeanServerFactory does. I did it this way because I didn't want to muck with the user's environment in respects to JMX.
Create a classloader MBean that just delegates to the parent and register it as the DEFAULT_CLASS_LOADER with the MBean server. I needed to do this so that the ServiceDeployer could create MBeans using the Thread.currentThread().getContextClassLoader()
Create my own ServiceConfig class/object. This is needed by old Kernel. This is pretty bare bones and incomplete. The creation of this should be moved out of the Kernel so that the directory structure can be plugged in.
Had to modify org.jboss.system.deployers.ServiceDeployer. If the classloader was not a RepositoryCLassLoader, then use a default ObjectName to load the JMX MBean
Created my own ClassLoaderDeployer to replace the ServiceClassLoaderDeployer. This just sets the top level classloader to be the context class loader. In the future, ServiceClassLoaderDeployer should be refactored to provide default classloader settings and factories so that we could scope deployments if desired.
Created a ClasspathResourceScanner that can deploy based on classloader resource path and also discover deploy directories based on a relative resource path
created my own JCA ConnectionFactory stylesheet that doesn't create an RMI binding for the DataSource by default. Basically use the old cf-binding template
Removed the client-deployer from ejb3-deployers-beans.xml
Removed AspectManager from aspect-deployer-beans.xml