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.
Related
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)
Well, this is my development environment:
I am using Java 1.8 and Eclipse 4.5.1 (Mars), J2EE tools and plugins installed to work with WildFly 8 as Application Server
I created a Java EJB project, with a simple HelloWorld stateless session bean class. It implements 2 interfaces: #Remote and/or #Local, where I defined a String getHelloWorld() stub.
Now, I have my client for consuming the EJB: A Dynamic Web Project with one Servlet.
Inside the servlet, I can inject the ejb class using annotations, like this:
#EJB
private HelloWorldLocal bean;
or
#EJB
private HelloWorldRemote bean;
As you see, I declared the bean as HelloWorldLocal/HelloWorldRemote types. However, if I want to deploy and run my application,
I need to put the EJB and Web projects into an EAR first. That allows the Servlet to know and compile the HelloWorldLocal or HelloWorldRemote bean types, by simply adding the EJB project on
the Build Path as Project, or even by putting the EJB project as a Deployment Assembly directive.
I'd like to create a client outside the EAR (a remote Swing application or Remote WebSite). That means my client will
have not the chance to adding the EJB project interfaces as project references in the build path as I did with the EAR. Even if I want to call
the remote bean with JNDI, I need to cast the lookup() object to those types in order to use the bean methods.
The question is:
How can I get the HelloWorldRemote/HelloWorldLocal bean types from my remote client without EARs, if those interfaces are declared into an separate EJB Project?
(Of course, I dont want to create a .jar with the EJB project here).
And what about portable JNDI lookup? https://docs.oracle.com/cd/E19798-01/821-1841/girgn/index.html It should work if the EJB in the same JVM as your client.
I'm not sure I completely understand what you're asking, and I haven't done this in years, but the normal approach for this would to to create an EJB client JAR containing only the client's bean dependencies and remote interfaces. To best accomplish this, you'll want to use a tool such as Maven to build your project which contains an EJB plugin for this. If you're not using Maven, you're going to be limited by the tooling within Eclipse, though at one point it did contain EJB client generation support. The Wildfly documentation on EJB client setup might help also, but explicitly mentions that packaging the client is out of scope.
I'd like to share the only one solution that I found: I have to create a .jar file, with all the EJB interfaces (#Remote, #Local, and so on), and use it like referenced types on my remote clients.
This .jar would be outside any EAR. however, it needs jboss-client.jar because of the # annotations. So, I packaged all, interfaces and jboss-client.jar, exported them to a .jar and I added this new file in my EJB and clients projects as external jar! Now I am able to use the HelloWorld* types on EJB classes implementations and #EJB client variables.
If I want a remote Web client, I've placed the EJB project with a Web Project module, into a EAR - Definitely we need an EAR. The Web module has Servlets, and the servlets handles the #EJB variables and responses. So, Outside this EAR, I just need to use URL's to the servlets and, you got it: EJB method results are reached from remote web clients.
In desktop applications with JNDI, I just put the interfaces .jar like external jar into the client project. In that way, I can cast the .lookup() to HelloWorld* types and using its methods.
I hope it helps.
Currently I am developing an application composed of basically three modules: 1 ejb and two web apps. Using ant I am exporting this as a single ear.
My client asked to run multiple instances of the same ear on the same server. I was able to change application names and context path so they do not clash, however there is a problem with EJBs. Apache Geronimo can't startup EBJs with the same name event if they live on different ear/jar, etç.
Is there any way to make the EJB deployment specific for each "installation", or isn't possible and therefore I need to strip EJBs Jar from the web apps enclosed on the EAR ?
I would appreciate any help/hint.
Regards,
Ivan Frias
If it will be enough to have the many copies of web applications with one EJB.
Then you can separate EJB module and web modules and then load one EJB and N copies of web applications in the application server.
But it may cause some errors because of one EJB for many web applications.
Otherwise you have to run three instances of the application server because you will not be able to use equal EJB even separated by different jars/packages.
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
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.