Glassfish: modify deployment descriptors for EAR during deployment - java

After several days of searching, trying and head-banging, I post this question to SO although it seems to be answered already.
Here is the scenario:
I have an EAR application containing (for the moment) one WAR and one EJB module. The EJB module uses JPA (persistence.xml) and some Stateless Session Beans are exposed via Web Services. The web services use Basic authentication with a jdbc realm. The web module uses form authentication with the same realm.
The requirement:
I need to be able to deploy this application either on different servers (dev/test/prod) or on the same server (or cluster) with different deployment descriptors. The deployment settings that need to be different in each application instance are:
The jta-data-source in persistence.xml
The realm-name in web.xml
The javax.faces.PROJECT_STAGE in web.xml
The webservice-endpoint\endpoint-address-uri and login-config\realm in glassfish-ejb-jar.xml
The context-root in application.xml (i could move it to web.xml if it made any difference, see below)
The realm in glassfish-application.xml
During my research, I managed the following:
I can override the javax.faces.PROJECT_STAGE using asadmin set-web-context-param
I can override all settings in glassfish-ejb-jar.xml using a deployment plan during asadmin deploy
The same applies for glassfish-application.xml
I can probably override context-root during asadmin deploy (I don't know how would this work with more than one web modules in the EAR)
So far so good. This leaves me with the following problems:
How can I easily modify the the realm-name in web.xml?
How can I easily modify the jta-data-source in persistence.xml?
By easily I mean during deployment or using something similar to a deployment plan jar. Maintaining multiple copies of ejb.jar or war just with a modified .xml file is not an option.
Just to be clear, the need is to have different databases (either in different stages of development or for different customers) using the same application. The application uses one persistence-unit but it needs to point to different databases (hence the jta-data-source). The realm is a jdbc realm (on the same database) that also needs to be different per application instance.
Any help or pointer would be greatly appreciated.

Have you thought about preparing templates for the deployment descriptors, and populating them with value from property file during build? If you are using ant, you can use the expandproperties filter.

You can do all those things with a deployment plan jar.
It looks like the content of the deployment plan jar is pushed into archive/directory tree of the application BEFORE any of the heavy lifting associated with deployment happens.
See
http://java.net/projects/glassfish/sources/svn/content/trunk/main/appserver/deployment/javaee-core/src/main/java/org/glassfish/javaee/core/deployment/DolProvider.java
and
http://java.net/projects/glassfish/sources/svn/content/trunk/main/appserver/deployment/dol/src/main/java/com/sun/enterprise/deployment/archivist/Archivist.java

Related

Spring MVC: Share beans between WARs in the same webserver

I'm running a web-server (Embedded Jetty) that hosts multiple WARs and also supports hot deployment of new\exisitng webapps (as described here).
I have a set of common beans which needs to be shared (same instance) between the different web-apps. Is it possible to use Spring to somehow handle this beans?
Found this excellent explanation, but it explain how to do it with EAR files, which is not an option on my side since as I mentioned we support hot deployment of new WARs, we don't want to redeploy all the web-apps when deploying one web-app.
Is it possible to use Spring to handle these beans? or do I need to create some kind of wrapper in my common-beans to behave as a singleton (all web-apps runs on the same JVM)

Put authentication/login configuration inside PROJECT

I implemented a custom login module I want to use with the JBoss AS 6. I followed some tutorial guidelines on the internet, namely http://x-techteam.blogspot.com/2007/04/jboss-custom-login-module-simple.html.
They write about configuring ${JBOSS_HOME}/server/default/conf/login-config.xml and deploy a JAR with the custom login module, but I don't like the idea of changing a configuration within the JBoss folder.
I really would like to have ALL configurations within my WAR file. The EE application I write will be sent to some customers and they should not have to worry about configuring some security contexts or roles via XML.
So my question is:
Can I have a local login-config.xml within my war that will be picked up by JBoss?
Can the custom login module class remain within my war, without having to deploy it to some JBoss folder?
Thank you in advance.
Use dynamic security domains:
link

Deploying multi-tier application

I want to build and deploy my first Java EE 6 multi-tier application, with web and business tiers running on separate physical servers on Glassfish 3.1.
I think I understand what's required from a theoretical hi-level view but am not clear on the specifics and small details.
My current plan as is follows:
Create a Maven Enterprise Application in NetBeans 7.
Expose Session Facade EJBs via remote interface.
Have JSF Backing Beans utilise Session Facade EJBs via JNDI lookup.
Deploy EJB JAR to one server and web WAR to the other.
I'd really appreciate some pointers on:
Application structure.
Correct JNDI lookup with separate servers. Is injection possible?
Building appropriate archives.
Deployment configuration to allow tiers to communicate.
Unless you know you will be serving many requests per second, or have very data and/or CPU-heavy business logic, then you should be perfectly fine starting out by deploying both tiers on the same application server. Starting out by deploying to a single Glassfish application server using local interfaces lets you skip a lot of complexity in the runtime environment.
This in turn will allow you to use the simplest form of #EJB-injection in the web tier to access the session facades in the business tier. Local intefaces are faster because the application server can pass references rather than RMI proxies between the tiers and it lets you skip the JNDI lookups. You can always change the annotation later on, or introduce remote interfaces if you later find other reasons to deploy the tiers on separate servers.
Glassfish supports clustering, so you might never have to explicitly separate the two tiers--it all depends on the actual usage patterns, so performance monitoring is key.
Deploying the web tier as a WAR and the business logic as an EJB jar is the right thing to do. Depending on the size and the logical structure of your application, you might want to break that down into to multiple modules.
Maven takes care of building the archives. Make sure you define a sub-project for each war and jar archive, plus a sub-project for assembling the EAR-file. The latter project will pull in the war and jar files produced by the other sub-projects. String all the projects together with a master maven project and voila, you have the flexibility to build each component separately, build the entire thing, or any combination in-between.
You have chosen a hard path, as others have pointed out in comments and answers...
Let's start with the structure of your app(s). You are going to end up with four achives... two that you will deploy:
a "regular" jar for the Remote interface of your EJB (jar-of-interfaces)
an EJB jar that has the implementation of your EJB
an EAR archive that will contain the jar-of-interfaces (in the /lib subdirectory) and the EJB jar (in the 'root').
a WAR file that contains the code that uses the Remote interface of your EJB. This will have the jar-of-interfaces in WEB-INF/lib.
The rest of this answer is based on the EJB FAQ. The most applicable part of that document is here.
You can inject the EJB into the ManagedBean. You will not need to use a dot-lookup method in your ManagedBean.
You will need to use the corbaname for your bean in the glassfish-web.xml file.

Application settings in a EJB3 app / maven multi module

What's the norm / best practices for saving/retrieving application settings in a EJB3 app?
I'm using maven as a build tool, and I have a multi module project.
I was thinking of putting some properties file on some common module that would be available application-wise as a jar but I'm not sure if an EJB is more suited for this.
Edit: The application properties should be configurable per environment.
My main issue is how to expose the properties to the rest of the container, my secondary issue is how to save them in a environment-dependent way
If the settings are to be changed on a regular basis then locking them in a properties file within a jar is going to make life difficult.
If the settings pertain to resources such as database or JMS connection urls, then those are best defined to the container and accessed via a JNDI lookup.
You could use context-param or servlet init-params in the web.xml, there must be something similar in the application.xml - I haven't looked at them in a while.
You could define them in an LDAP, and then extend the JNDI tree to include that branch.
Although I would probably just use a properties file located in a directory on the classpath outside of the ear/war/jar deployment structure.
What's the norm / best practices for saving/retrieving application settings in a EJB3 app?
EJB3 app is very vague... But I would say that things like an endpoint URLs for external services would typically go in JNDI as environment entries (that you could then inject with the #Resource annotation) if you want to maximize portability.

OC4J 10.1.3.4 problem with deploying multiple 2.1 EJBs

I am having troubles migrating from OC4J 10.1.2.3 to 10.1.3.1.4. The problem is for applications that have multiple EJBs (all are 2.1, no EJB 3.0). Jdeveloper will take the default ejb-jar.xml (the one required for Jdeveloper to run it on its stand-alone OC4J instance) and package it into each EJB JAR module NO MATTER what. This results in the app server drilling into each EJB JAR module when deploying, and find the same ejb-jar.xml file N times (where N = number of EJB Modules). This results in duplicate EJB references and will break any JNDI lookups such as: "java:comp/env/ejb/EJBName". Thus deploying an app that has 3 EJBs, EJB1, EJB2 and EJB3 causes the app server to register 9 EJBs instead of 3. I need a best practices way, but in between the way 10.1.3.4 and JDeveloper are acting the situation is rather dire...
Side note: They will work if the web app's JNDI look-up code is refractored to just "ejb/EJBName". This is not desirable though.
You should check the Oracle documentation to see which is your case.
The Oracle® Containers for J2EE Enterprise JavaBeans Developer's Guide is a good start
According to the Oracle® Containers for J2EE Services Guide, chapter 2: Using JNDI
when you use the form "ejb/EJBName" you perform "local" lookup. If you want to use the full form you must check the "Enabling Global JNDI Lookups" section of the "Using JNDI" chapter.
The problem was multiple reference in our deployment profiles. We were create a deployment profile for EACH EJB. This meant that each EJB had it's own ejb-jar.xml (this file contained a description of all EJBS in the project). Therefore, every time JDeveloper created an EJB, it placed a descriptor of all EJBS in each EJB it generated, causing an NxN amount of references. Therefore Nx(N-1) extra references.
Now, the key point is that Oracle Application Server 10.1.2.3.0 and bellow did not care about these duplicate references. However as we can see, 10.1.3.1.4 is a much different version and this did break.
Our fix: to have only 1 EJB Deployment profile that contains all of the EJB classes and the POJO's that they use. Remember, before there was 1 EJB Profile for each EJB... All this did was allow for Jdeveloper (which is crap IMHO) to correctly generate a valid EAR. A combination of Jdeveloper and Oracle's Application Server's crap is what caused this.

Categories

Resources