Glassfish - share EJB web application between nodes - java

I've got a glassfish server with a couple of EJB wars deployed on several different nodes. I want one of the applications (deployed on node1) to be 'visible' to all applications deployed on different nodes, so that they would be able to inject some remote beans from it. However, I am allowed to have only ONE instance of this application for the wole server, so deploying it separately on all nodes is not possible.
Is this kind of setup possible in glassfish 3.1?

This is achievable through deployment descriptors:
https://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#cross-appserverremoteref
In your sun-web.xml (or glassfish-web.xml, both will work in this case) define ejb-ref as follows:
<ejb-ref>
<ejb-ref-name>fooejbref</ejb-ref-name>
<jndi-name>corbaname:iiop:node_name:node_IIOP_port#foo.bar.YourEJBRemote</jndi-name>
</ejb-ref>
It's not exactly convenient - you will need to define that for each remote bean you need, and add such a descriptor in every app that needs it. It should however work, and I don't know of any better way.

Related

Java EE deployment issue

I'm running into some issues in deploying my Java EE application, and could use some advice.
I have 3 components to deploy:
Integration layer (Data): POJOs and CDI Beans - JAR file
Application layer (BL): EJBs, CDI Beans and POJOs - JAR file
Presentation layer: Servlets and such - WAR file
Optimally, I would like to be able to deploy both the integration and application layer JARs in the same Java EE server, but as separate JARs (since I might want to change the hardware configuration later on and separate them into two different servers on two separate machines).
The problem, is that I'm unable to get the CDI injection from the integration layer JAR to the application layer JAR to work. The server says (and probably rightfully so) that it's impossible to resolve the injections.
So far I came up with these possible solutions:
Package the two JARs into a single EAR file (maybe throw in the WAR as well ...), and deploy that
Use JNDI between the different layers (possibly create a CDI producer to do a generic injection based on JNDI names or something like that)
In the integration layer, make the objects being injected into the application layer (the DAOs) EJBs instead of CDI beans
I don't like either of these solutions (especially the last), since they restrict my future deployment options. The second solution does not restrict me, but it might become tedious at some point (when I accumulate a lot of code).
Finally, my question is:
Is there an option I didn't find yet, that would allow me to deploy the two JARs on the same server with the CDI injections working ? Possibly something that would still work if at some point I separate the JARs into different servers ?
Yes, there are other options as well.
Use a java EE container that supports OSGi as well, and use OSGi interface for your deployment dependencies. At least Websphere, Glassfish, JBoss (with jbosgi installed), Jonas support deploying OSGi bundles. This means your modules should be converted into OSGi bundles.
Use a container-specific extension that allows modules to communicate between each other. JBoss as jboss-deployment-structure.xml that you can use to have a dependency to another deployment.
Use a server-provided shared classpath for your dependencies. Wouldn't really recommend this.
My vote would go for OSGi.
None of them will work by themselves however if you deploy packages to different servers. A remote technology like remote EJBs, remote JNDI lookups, Spring remoting, HTTP-based api, CORBA or similar is needed between different servers. In Java EE, EJB is the de-facto standard for this, but Spring remoting is not bad either.
Update: you added that you use TomEE servers. Indeed TomEE won't support the first two options I mentioned. I would use EJB in that case - the fact that you're using EJBs can be abstracted away from the business layer using an EJB delegate, and you could use EJB (stateless session bean) only for the interface part, leaving your DAOs as POJOs.
not sure what your goal is but deploying a war is fine, can even be done manually with these commands:
mkdir -p webapps/myapp/WEB-INF/lib
cp myjar*.jar webapps/myapp/WEB-INF/lib/
If your goal is to be able to split them you can use TomEE skinny war feature.
Create a war with a WEB-INF/jars.txt file.
In this jars.txt put one line by dependency/jar. It can be the path to the jar or maven coordinates.
Once setup it will allow you to change jars one by one then simply restart the server. This is great when several teams work on the same binary.
There are some alternative with TomEE but this one has the advantage to be easy to change to a portable one (war).

Deploy a WAR file on JBoss only if JNDI resource is available

I have a multi-tier project where the application server that provides an access point to the web should deploy its WAR file only if required remote JNDI resources are available.
The JNDI lookup is performed on a different server within the local network, where no access from the outside world is allowed.
My problem is that right now, there is no way to tell if any of the required EJB modules are in place before starting deployment of the WAR - which will fail miserably if a JNDI lookup is not resolved (the remote services are used with Dependency Injection, so they must be present at startup).
Of course, I could set up a timer in my Maven build to wait for an arbitrary number of seconds between deployment of the modules, to allow the EJBs to start, but that seems like a crude hack to me, and it will not be very reliable, depending on which machine does the build.
I would be happy both if an JNDI check can be done directly on the application server, or within the Maven build, prior to deployment.
Is there something like that? I found this question, but there never was an answer...
I haven't tried it, but this should be possible with #Resource, or by creating WEB_INF/ejb-jar.xml and using lookup-name. See https://community.jboss.org/thread/213106.

Does EJB container reside in all application servers. EJB container in depth

I am newbie to EJB's. From all the reading and searching I have done till now, I understood the following:
EJB are the beans in which an applications business logic is written and maintained.
All EJB's are put into something called EJB container.
EJB container is nothing but a server side program written in order to manage EJB's, and to provide basic functionalities which are meant to be provided by EJB(viz, transaction management, security, collision free envt, etc).
1) My doubt is, does the so called EJB component reside in all application servers?
2) When we say EJB 2.1/3.0/3.1, does it mean that the new version of EJB container has been released?
3) Does the EJB container reside in web servers too?
Thank you.
You understood the EJB idea correctly.
Yes and no. Depends on what you understand as "Application server" (ambiguity described below in answer 3.)
When you say EJB 2.x/3.0/3.1 or so on, you're referring to a particular EJB specification which means that you're referring to a set of services this version supports. In other words - yes, it means that the EJB container must be in a given version.
First the specification is released (you can see the draft versions, vote for new features and basically participate in this process). Then, a reference implementation (RI) is written just to show that it's "doable" and you can use it right away. Then, different vendors might provide their own EJB containers which must conform to the particular EJB specification.
There are few different terms you need to be aware of. Just to be sure, we're talking about the same things:
Web server is a HTTP/HTTPS server like Apache HTTP Server which serves clients requests. This term is not only related with Java EE.
Web container is a Java EE term which can mean few things, but usually it refers to Servlet container and, let's say JSP container. Those containers are serving web clients, so that's why it's web container. Generally, web container have a web server within it (like in the case of Tomcat.) However, you can configure it so that the static resources will be server by only pure web server while dynamic content (your Java App, Servlets, JSP, etc.) will be server by your web container.
Application server is a vague name. In Java EE purists world it can mean only such server that provides all the Java EE services. Non-Java EE purists treats Application server just as an arbitrary server which consists of your application. According to this definition, you can call Tomcat (a web container and web server) an application server.
As you see, the vocabulary is not sharp, as one thing might mean few slightly different things. Moreover, since Java EE 6 we have profiles. This means that you can have Java EE Application Server conforming to the Web Profile or Full Profile. In such terms, just the Web Profile server should be treated as an application server.
Just as a summary - you can use EJB Container in Web Container. Take a look at OpenEJB or basically at project TomEE.
To answer your questions
Generally yes. Application server is generally referred to a server with has EJB container like Glassfish, Jboss etc. But you need make sure that the application server has EJB support.
YES
NO. Web servers or Web containers (Tomcat, Jetty etc ) serve a different purpose than EJB container. But all the application servers do have web servers (along with EJB containers. ).
The EJB container and web container (servers) server are different layers in a Java EE application scenario . Check this link for more info.

Communication between EJBs deployed in different Application Servers from different vendors

I ‘m trying to create a small EJB 3.1 application in which I want to use two application servers from two different vendors. (JBoss 6.1.0 Final and Glassfish 3.1). This is just to experience the taste of distributed applications and new features of EJB3.1.
This is the problem I’m having…
I have created a simple EJB (kind of a hello world ejb) and deployed it in GlassFish server which is running in the machine A. Let’s call it GlassFishHelloWorldEjb. This one has business remote and local views.
I have created another EJB project in which I have an EJB called JBossHelloWorldEjb. I have deployed it in the Jboss server which is running in the machine B.
Now I want to inject GlassFishHelloWorldEjb to a reference in the JBossHelloWorldEjb so that I can call it within the JBossHelloWorldEjb. Then I have a web app deployed in the Jboss which calls the JBossHelloWorldEjb.
MyWebApp(Jboss, machine B)-----> JBossHelloWorldEjb (Jboss, machine B)----> GlassFishHelloWorldEjb(GlassFish, Machine A)
I tried many ways to inject the GlassFishHelloWorldEjb in to the JBossHelloWorldEjb but failed. Could some please shed some light to achieve this.
Would greatly appreciate if you could show me the way to do this through both INJECTION and Programmatic JNDI look up.
Cheers
Lekamge
one option might be to use Spring RemoteEJB Proxies
OR. import client required jars for remote and write your own wrapper

EJB3 Local and Remote interfaces

I understood that Local interface is designed for clients in the same container's JVM instance and remote interface is designed for clients residing outside the EJB container's JVM. How about the web application client which is not reside (or packaged) in the same .ear but reside on the same Java EE server?
Officially #Local annotated beans can only be accessed if they're in the same application. A .war deployed separately from an .ear (or other .war or other .jar EJB) is a different application, even when deployed to the same application server instance.
There's thus no guarantee that the code in your .war can call #Local EJB beans that are defined in the .ear.
However, in practice in nearly all application servers this just works.
There's a request for the EJB 3.2 spec to officially support local cross-application calls: https://download.oracle.com/otndocs/jcp/ejb-3_2-fr-spec
Local interfaces are to be used in communication within the same application. It doesn't necessarily mean JVM.
The point is: even within the same JVM instance, on the same server, two different applications cannot communicate using local interfaces (which means local and no-interface views).
If you have a web component (WAR) as well as a business component (EJB-JAR) which is in the same application, the most intuitive and straightforward solution is to package them in one EAR or in one WAR (since Java EE 6).
You use the remote interfaces, but you make a lookup using JNDI (that's how i'd do it), this way you find the instance of the EJB in the server and can use it in your web application.
Although you still need a jar with the EJB interfaces in the web application project.
EDIT and I agree with JB Nizet, why would you want the WAR outside the EAR?
Remote interfaces can be called across applications, from everywhere within the application server as well as from outside, even from other hosts.
So assume that you need remote (#Remote) interface. In EJB 3.1 you can use dependency injection.

Categories