JBoss EAP 6.x understand the deployment phase - ResourceAdapters, EJB, jar, war - deployment

In JBoss, how is the sequence of the deployment phase? What is the order of object being instantiated and available to use?
Considering an enterprise application (*.ear), inspecting all deployment log (server.log) the deployment phase looks like:
All libs are deployed - .class files are loaded and available;
All *.jar modules are deployed - .class files are loaded and available;
If some *.jar is an EJB Jar, through the configuration files (Ex. ejb-jar.xml) or annotations, the JNDI tree is created;
If some *.jar has a persistence.xml file configuration, all entity and link to datasources are loaded;
All *.war modules start the deploy phase;
Through configuration files (web.xml), listeners and context-root are loaded and eventually security aspects.
Ear deployed successful.
Questions:
What about the resource adapters modules, the PersistenceContext and the EJB Pool?
When a persistence.xml is found, does a connection to the data-source and so to the DB pool start?
Since the datasource (DB) is configured in the standalone.xml or domain.xml, when happens the first connection to the DB pool? When I inject the PersistenceContext and use the EntityManager?
When the EJB pool is loaded and available to use?
Is correct to say that during the EJB jar deploy, the JNDI tree is created and then available?
When an EJB is discovered, it's loaded inside the pool (as reference to inject/lookup)?
When a .war module is deployed and ready, even if the full deploy of the .ear is not completed yet, possibly servlet or listener are started from the container.
What happens if some of this objects (listener, servlet) try to use EJBs or PersistenceContext or other objects? Are those objects available?
Is it possible to have deadlock problem and hang the deployment thread/phase?

It is possible to control the deployment order of jars and wars in application.xml using <initialize-in-order>true</initialize-in-order>
The lifecycle of the resource adapters is controlled by the connector architecture
The lifecycle of Container-Managed Entity Managers are managed by JBoss. Assuming you are injecting into an EJB using #PersistenceContext, this happens prior to #PostConstruct.
Singleton EJB initialization order can be defined using #DependsOn("OtherBean")
You can ensure the EJB endpoints are available using the deployment order in the first bullet
Not sure if it is possible to dead lock - it is far more likely that you will see a JNDI exception

I will try to address the rest of your questions:
When a persistence.xml is found, does a connection to the data-source
and so to the DB pool start?
Yes, that must happen (if no connection already is made), otherwise no table structure (DDL) could be validated or be created.
Since the datasource (DB) is configured in the standalone.xml or
domain.xml, when happens the first connection to the DB pool? When I
inject the PersistenceContext and use the EntityManager?
The answer to this question is: it depends. If your JDBC Datasource is configured with a minimum pool size MIN_POOL_SIZE>0 and has the prefill flag set to true, then WildFly will create MIN_POOL_SIZE connections to the DB server, without any deployments at all that use that datasource (after changing that flag you will need to disable/enable the datasource). Otherwise on deployment: it is created as many connections as needed (depending on what you do on deployment, but for simple applications a single one), except you have a MIN_POOL_SIZE>0 defined and the strict minimum flag is set to true, in which case AT LEAST MIN_POOL_SIZE connections will be created.
When is the EJB pool loaded and available for use?
It is available for use after deploying the EJB submodule, with all its dependencies.
Is correct to say that during the EJB jar deploy, the JNDI tree is created and then available?
I would formulate that in the following way: After (not during) it is checked that all EJBs can be deployed (e.g all their dependencies could be solved), then JNDI entries are created (in the JNDI tree). According to what I noticed, if a single EJB fails, nothing is deployed, which makes me think I am right here.
[When a .war module is deployed] What happens if some of this objects (listener, servlet) try to use EJBs or PersistenceContext or other objects? Are those objects available?
Yes, definitely. We use that feature to execute some init code from a servlet, when the WAR file is deployed (e.g to create some entities with some default values).
Is it possible to have deadlock problem and hang the deployment thread/phase?
Theoretically yes, practically no (I doubt the guys at RedHat did not think about this).
Some tips: if you use MySQL, you can check what connections are made to the server with show processlist. Otherwise if you use Linux/Unix, you can check all made connections to your DB server with netstat.

Related

What to put into jta-data-source of persistence.xml that works on all vendors?

Similar to What to put into jta-data-source of persistence.xml? and How to map jpa datasources in WildFly?
However, I am asking for something that would work on all vendors or at least WildFly, Glassfish/Payara, WebSphere Application Server classic, WebSphere Application Server Liberty, TomEE. I am not looking for something that works in a Java SE Unit test.
So far I found that java:comp/env/jdbc/xxx works in WebSphere Application Server and TomEE. There's a mapping exercise (which is expected) to get it working but I cannot get the same to work on GlassFish/Payara and JBoss/WildFly.
More specifically I do not wish to use default data source because for my scenario I am actually working on two different data sources. E.g. for reference data and another for transactional.
If all of the app servers you work with are Java EE 7 compliant, you can use the default data source, which is required per EE7 spec to be available at:
java:comp/DefaultDataSource
The app server you run on ought to let you customize the configuration of the DefaultDataSource.
Since I'm familiar with WebSphere Liberty, I can point you to this doc for default data sources on Liberty:
Configuring a default data source
If you are using WebSphere traditional, as of v9.0 it supports Java EE 7, and has a default data source available out of the box (under the spec mandated JNDI name).
If you want to use the same JNDI name that works on all servers, it's best to use resource references, as explained in What is resource-ref in web.xml used for?
Basically, you would define an arbitrary JNDI name (ideally without any java:comp prefix or similar, just something like "myDatasource") and then map it to the concrete JNDI name provided by the target server.You would need to define a server-specific descriptor for each server with the mapping the if the server cannot use the JNDI directly (e.g. glassfish-web.xml for GlassFish/Payara, jboss-web.xml for WildFly, ibm-web-bnd.xml for WebSphere Classic and Liberty). TomEE seems to support references without any prefix, so it should be able to configure a datasource without any additional mapping if you choose a name without a prefix.

Including the MySql's connector/j as part of an EAR file: Glassfish

We want to simplify the deployment process of an app by including the MySql connector/j jar as part of the EAR. (so we won't need to manually copy it in the /lib folder of our Glassfish servers)
Is it possible?
UPDATE: We have read this is possible using the SAR files in JBoss, but we don't think it's available in Glassfish.
Because of the classloader hierarchy in Glassfish I don't think this is possible. The mysql driver jar needs to be available outside of your application's classloader because the connection pool is globally available.
http://download.oracle.com/docs/cd/E19226-01/820-7695/6niugesfp/index.html#indexterm-28
From what I can find, Glassfish doesn't support anything like .sar files:
http://old.nabble.com/Migrating-From-jboss-4.2.1-to-GlassFish-td18629992.html
Maybe vote for this issue, or create your own for a .sar-like deployment option:
http://java.net/jira/browse/GLASSFISH-16915

How to do Application specific Configuration for a Framework

i want to write a Java EE framework for a generic type of applications.
I'm looking for a way to handle application specific config values in my framework.
To give an example:
A component supplies a stateless session bean that handles persistence and i want to configure the name of the datasource that is used in a config file in my application (for example in the web-inf folder of the applications ear).
Now i have X>1 Applications that want to configure X different datasources for their specific persistence management.
Can anybody give me an example how to do that?
Greetings,
Alexander
You should use the JNDI provider thats bundled with the application container. One of its purposes it to access resources, data sources in your case, in a highly dynamic fashion.
For JBoss, setting up a data source involves the following steps:
deploy a *-ds.xml configuration file to the JBoss server's deploy directory. This defines the global JNDI name of the resources. There should be plenty of examples for a lot of databases available on the internet.
add a resource-ref to the jboss-web.xml of any WAR or to the jboss.xml of any EJB jar for any bean that needs the resource. This defines the global JNDI name to local/component JNDI name mapping.
add a resource-ref using the local JNDI name to the web.xml of any WAR or to the ejb-jar.xml of any EJB jar for any bean that needs the resource.
Once those things are in place, you can perform JNDI lookups to access the configured resource.
You can do these things to configure multiple data sources in JBoss and then make one or more of these data sources available to the web applications and EJBs.

Separate JSF and EJB apps

How do I use a deployed EJB app from a separate JSF application?
I'm attempting to separate the two applications and access the EJB through the remote interface. To do this I have two eclipse projects - one contains the EJB and persistence logic, tested independently and works. I then created a JSF project that references the EJB project (so I gain access to the remote interface), however this fails when attempting to either inject the EJB instance or lookup the JNDI name (I've tried several variants to no avail). This is what my JSF backing bean contains:
#EJB(lookup="java:global/LocEJB/LocalityEJB!com.ame.business.LocalityEJBRemote")
private LocalityEJBRemote locality;
This is on Glassfish, and I am only referencing the EJB project and not packaging it with the JSF project. When I do the latter, I receive error initializing EJB container problems on the JSF project. So, how do I access the remote EJB and does the way I'm approaching this make any sense?
Thanks in advance!
Your JSF application has to know about the EJB interfaces (at least they did on EJB 2.0). You're using the Proxy pattern to hide the fact that this is a remote component from your JSF client.
First of all you can not use Local interface if trying to access outside the container. You must use Remote Interface.
You can define your Remote interface in the sun-web.xml or EJB injection in the bean.
sun-web.xml code:
<ejb-ref>
<ejb-ref-name>com.xxx.session.UserRemote</ejb-ref-name>
<jndi-name>corbaname:iiop:127.0.0.xxx:3700#com.xxx.session.UserRemote</jndi-name>
</ejb-ref>
Another thing you must have Remote interfaces in your classpath.

Deploying multiple versions of same EJBs and classes to same JBoss server

I have a few separate application projects (EARs) with multiple EJBs that I want to deploy to the same JBoss server. Now, some of the projects may have the same EJBs, but different versions. In similar circumstances, some projects may use different versions of the same "ordinary" classes (i.e. classes loaded within VM, without JNDI lookup).
With OC4J, this seems not to have been a problem, but now with JBoss, I get the impression that everything resides in the same "name space" (or class loader perhaps). Am I correct in this assumption?
Basically, what I want to do (or ensure) are two things:
From a client that does a JNDI-lookup of an EJB, I want to be able to indicate which application it resides in, so that the correct version of the EJB is returned.
From within an EJB, when instantiating a class, I want to ensure that the class is the one deployed with the same application (EAR) as the EJB was.
I think I read that you could configure some "isolation" properties for EJBs, am I guessing correctly in that might would solve my second point?
JBoss's default behaviour is to use a flat classloader. This reduces the footprint, but as you've found, it makes deploying multiple applications troublesome.
Thankfully, the fix is easy. In the ear-deployer.xml file in the deploy directory, make sure the following parameter is set:
<attribute name="Isolated">true</attribute>
This will give each deployed EAR its own classloader space. It will still be able to access stuff from the JBoss lib directory, but the deployed EARs will be invisible to each other.
You're correct that classes from different EAR's reside in the same "space". JBoss uses by default a flat classloader hierarchy, meaning that all classes (except for WAR packaged ones) are loaded by the same classloader. With the introduction of JBoss 5 there's a new standard profile that strictly follows the Java EE rules and thus supports isolated classloading. Older JBoss versions also support this behavior through the callByValue and isolate properties in the deployer configuraion.