I started developing project where weblogic is used as webserver. In this project, we have several war files merged into one ear file. Now, I need some functionality (dao access) from one war file in another waqr file. Is it possible to use EJB or java Injection to get an instance of dao object from one war fle in second war file?
The easiest way to do this is to move the dao access classes up into the EAR file where both web modules will have visibility of the classes.
Individual web modules (war files) each get their own class loader and are unable to see each other's classes.
Related
I have an Enterprise project (EAR) with one EJB and several web modules, these web modules have lots of classes in common, they are exactly the same for each project, so if I modify one of them I'll have to manually copy the code to the other projects as well. I don't want to put them in my EJB module because they use a lot of front-end related resources.
Is there a way to share these classes between the web projects?
Obs: They also use classes and resources from the EJB module.
Make another module with all commun classes and package it as a Jar. Then add the jar as a dependency to the other project.
Maven should be a good tool for this project.
There is no way to have shared classes outside of a .war which are capable of having web-specific resources injected.
I would refactor the common classes into a separate .jar. You could make them EJBs, or just regular classes. Either way, you won't be able to inject web-specific resources; the classes in .wars will have to pass such things as method parameters. In the case of EJBs, you can't directly pass non-serializable objects like HttpServletRequests; I don't know if that will create a significant impediment.
An EJB .jar can be placed anywhere in the .ear, but if you choose to make a non-EJB .jar, it can be placed in the lib directory of your .ear file. It's also a good place for EJB interfaces, if you aren't writing no-interface EJBs. From the Java EE specification's "Application Assembly and Deployment" chapter:
A .ear file may contain a directory that contains libraries packaged in JAR files. The library-directory element of the .ear file’s deployment descriptor contains the name of this directory. If a library-directory element isn’t specified, or if the .ear file does not contain a deployment descriptor, the directory named lib is used. An empty library-directory element may be used to specify that there is no library directory.
All files in this directory (but not subdirectories) with a .jar extension must be made available to all components packaged in the EAR file, including application clients. These libraries may reference other libraries, either bundled with the application or installed separately, using any of the techniques described herein.
My organization is creating a "base" Java web app that is meant to be customized by adding jar files (with customized classes) by adding the jar files to the web app's WEB-INF/lib directory. The goal is that our developers can simply create custom code, packaged as a simple jar file, which can be loaded into this "base" web app, so the developer doesn't have to worry about all the web app plumbing, just the actual custom code.
We're investigating a few different deployment models, but one idea was to put these jar files somewhere on a network directory. When the Java web app starts up, a ServletContextListener copies these jar files into the web app's WEB-INF/lib directory (the web app is originally deployed as a war file).
Then, another ServletContextListener uses Stripes' ResolverUtil class (JavaDoc here) to load all of the classes of a particular type (in this case, that implement a particular interface) that are located in the jar files that were copied into WEB-INF/lib.
Unfortunately, ResolverUtil fails to find those classes, even though they are in those copied jars. If I restart Tomcat (with those jar files still in WEB-INF/lib) they are found, as expected.
The jar files need to be in WEB-INF/lib because we want to use the Servlet 3.0 feature in which JSPs can be served from jar files, and for that to work, apparently those jar files need to be in WEB-INF/lib. If that weren't the case we would just add those jar files in the shared.loader property in catalina.properties.
So, it appears that Tomcat has already scanned the classpath for all class definitions by the time a web app is started, and since those jar files weren't in WEB-INF/lib when the web app started up, the classes will not be found.
Is there a way for those classes to be found? I don't need Tomcat to completely reload itself; I just need those new jar files and the class files they contain to be visible to the class loader. Is there a way to tell the classloader, "Hey, check the classpath again for new jars!" as I would only need to do it once, when the web app starts up?
Any other ideas?
Thank you!!
I have a JAVA EE Project, containing both EJB and WAR projects inside of it.
I want to be able to access WAR project class from the EJB project class.
I have access the other way ( I can access ejb class from war).
Is that possibble? How can this be done?
Thank's In Advance.
I assume that you have got an EAR with two modules inside, WAR and EJB JAR. As both modules are independent, they shouldn't depend on each other. What you want to do is possible via MANIFEST.MF Class-Path entry in module META-INF folder, but I strongly discourage you to do so.
You can re-factor you application to following structure:
EAR/
ejb-app.jar
war-app.jar
lib/
common-libraries.jar
Just putyour common libraries to separate JAR (regular java project), and add it to ejb-app and war-app classpath.
Alternatively you can implement EJB's in WAR project as they are supported in WAR since Java EE6.
I plan to deploy an EAR packaged application into JBoss v4.2 as a folder containing the content of the EAR. Until now the EAR is deployed as a single file. I hope to be able to replace single JARs without the need to restart the application.
Is there any kind of event listener or annotation that can be used to register those JAR files upon deployment? The idea is a plugin like deployment of some features implementing a known interface. The plugins shall be used in a Seam webapp environment and may be exchanged with updated versions on the fly.
Any ideas? Thanks.
AFAIK, this is not possible/supported. When using an exploded EAR, touching an individual module would trigger the hot deployment of the whole EAR.
From Lightweight Java Web Application Development: Leveraging EJB3, JSF, POJO, and Seam:
3.4.2. Hot Deployment
Another JBoss feature that helps agile
development is exploded archives. The
EAR, EJB3 JAR and WAR files are not
necessarily JAR files in the JBoss
container. They can be directories
containing the contents of the JAR
file. For instance, instead of
deploying the dvdcatalog.ear file as a
single file, you can deploy it as
directory.
With the exploded directories, you can
make changes to any single JSP page or
Java class file in the application
while the server is running. Then you
can touch the META-INF/application.xml
file in the exploded directory (i.e.,
update the file's timestamp to
current) to re-deploy the entire EAR
application. This further saves
significant amount of time for rapid
turn-around agile developers.
What you're looking for doesn't sound simple. It would require detecting the change, unloading loaded class definitions coming from that JAR (assuming this information is known), reloading classes (something like that but I'm pretty sure I'm oversimplifying). Maybe more a job for an OSGI server.
See also
JBossClassLoadingUseCases
ClassLoadingConfiguration
I have an ear which consists of 2 war files one containing junit classes and the other one containing actual application classes which are referenced by the junits.
Now when executing the junits i get a java.lang.NoClassDefFoundError
Is it due to the junit class files are located in different ear and hence not able to access the application class files that are located in another ear ?
OR
Whether this is due to the issue with deployment, Though i am able to run the application as well as some of the junits which are independent of application classes located in the other ear ?
According to the strict JavaEE visibility semantics, classes inside a WAR should not be visible to other components of the same EAR. JBoss relaxes this a fair bit, and tries to flatten out the classloading hierarchy to make it less irritating, but the WAR restriction still stands.
The solution I use is to put only web resources into the WAR, and to put the WAR's class files into a seperate JAR inside the EAR. That way, the webapp itself can find the classes, and so can your unit test webapp.
The correct way is to move the common classes into a dedicated JAR, and bundle that at the EAR level. So you will have a structure like this:
business-logic-jar
main-web-app-war
test-web-app-war
application-ear
You can bundle the JAR as well as any other libs you depend on in your EAR, and reference them using the manifest file of your WARs. In MANIFEST.MF it looks like:
Class-Path: business-logic-1.0.jar spring-2.5.5.jar ...
You can still bundle additional JARs inside each WAR's WEB-INF/lib folder, e.g. junit inside the test-web-app-war. If you are using Maven, read the skinny war page for a general approach.
JUnit classes don't belong in WAR or EAR files. They shouldn't be deployed.
You don't say which app server you're using, but if you use WebLogic you can put all your .class files into APP-INF/classes. They'll be visible at the EAR level then, so all WARs can see them.