I have two projects that share some resources, some of these resources are images, property files ... I wonder how I can get the two projects to access these resources without duplicating them.
I am working with the eclipse IDE, I just want to refer to them to avoid duplication.
The projects are two web applications, my only development framework is JSF.
By default, the resource handling mechanism introduced in JSF 2.0 looks up resource in the following locations:
In /resources under the web application root folder.
In /META-INF/resources in JAR files.
You can set another resource folder inside your context root (wich by way is inside your project and you can't point to an external resource) by adding
<context-param>
<param-name>
javax.faces.WEBAPP_RESOURCES_DIRECTORY
</param-name>
<param-value>/path/to/resource</param-value>
</context-param>
to your web.xml, but i wrote this only for educational purpouses because you can't leave the scope of your app folder.
So your only viable option is to "cook" your own jar with your images and property files added in /META-INF/resources. Then add your jar as an external jar to your project and you are good to go.
IMHO you should use Maven, this is what I use to manage projects dependencies. You would either need to put the resources into one of the projects or create a separate project (jar) that both can share.
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.
I have a web application developed in JAVA and I have a jar file. I would like to add the jar file to the application class-path. I know a web application includes libraries from WEB-INF/lib/* but I want to include a jar under this location C:/myLib.jar. Is that possible, if it does how can I do it?
regards,
micuss
ok, jboss is a bit difficult on classloading, but its definitely possible.
you need to add a new jboss module for your external jar and then declare your web application to depend on that module.
there's a complete guide for this here.
its possible to define a module to reference a jar file completely outside the jboss folder (c:\mylib.jar in your case) but it'll be easier on you if youre willing to move the jar into /modules
see here for complete documentation on how to write module descriptors. you can set the path to lead to your external jar (but its gonna be ugly)
This question already has answers here:
How to add JAR libraries to WAR project without facing java.lang.ClassNotFoundException? Classpath vs Build Path vs /WEB-INF/lib
(5 answers)
Closed 7 years ago.
I've seen a lot of tutorials and applications that put their jars inside a build path while others put it inside their web-inf/lib folder, Are there any significant difference? What are the pros and cons of both? What is an indicator for me to put a certain jar inside the libs folder and put the jar in the build path?
An application with WEB-INF folder is a web application. Meaning it will be packed as a WAR file and deployed on a server.
If you are using an IDE like eclipse, and you export the project as a WAR file, it will automatically take jars under the lib folder and pack them with the WAR and that will make them available for the application running on the server (jars under WEB-INF/lib are included in the application classpath).
If you just put them anywhere else and include them in the build path, when you export the project you have to declare that you want the jars in the build path to be included as well.
Basically, there is no big difference but if you know you need this jar in runtime (i.e. after deploying the application to the server), it is better to put it under the WEB-INF/lib folder.
What do you mean by build path? Most of the JARs you use need to be available during building (compiling) because your code depends on them - otherwise it won't compile.
The real question is between placing JARs in WEB-INF/lib vs. your container /lib directory. In general you should always put your JARs inside an application in WEB-INF/lib. Placing them globally has several consequences:
singletons are now global to all web applications (one class loader) if multiple deployed
it's easier to introduce memory leak if a library holds a reference to any of your classes (see above)
you don't duplicate the same classes (each web application will reuse the same class as opposed to having a separate copy in each class loader
I run many instances of the same web application under Tomcat and to save memory I copy some of the libraries to Tomcat's lib (tomcat\lib) and shared (tomcat\shared) folders. Libraries that go under lib can be found by both Tomcat and web applications, libraries that go under the shared-folder can only be used by web applications. My web application also need some libraries on the web application level so those libraries goes under WEB-INF\lib.
I have defined in my pom.xml that most libraries have a scope of provided so that they're not copied to WEB-INF\lib, however is there any way to define that I would like some libraries to go under a custom-defined folder; e.g. WEB-INF\lib\tomcat\shared and WEB-INF\lib\tomcat\lib, from where I could mover them manually to Tomcat's corresponding folders on the server?
That is not really the recommended way to package dependencies, as usually the web application would be deployed without furhter modification of the war file.
I think you can archieve what you want using the dependency:copy-dependencies goal, but it would require some configuration. You would have to set includeScope to provided, set the correct outputDirectory and then define the artifacts with the includeGroupIds or includeArtifactIds options.
Make a separate maven project which contains the war file and define the dependencies which should be located in the share-folder as scope: provided. Furthermore create an other separate module which has these dependencies and create an appropriate archive from it via maven-assembly-plugin...
I imagine this is simple - but I can't find the right combination of search terms to get an answer. If I have a multi-module application, how do I get the beans in module A available to the beans in module B.
The project setup looks a little like this:
project.ear/module-a.jar/resources/beans.xml
project.ear/module-a.jar/java/foo/bar.class
project.ear/module-b.war/java/foo/barFactory.class
The beans.xml isn't accessible by either classpath, or filesystem. Is there a way to do this? Or should I be doing everything differently?
Your appserver is likely using different classloaders for each module in your EAR, preventing one module from seeing resources in another. This is the default behaviour of JavaEE classloaders.
You either need to
reconfigure your appserver to use a "unified" classloader across the whole EAR (which is highly appserver-specific, but great if you can get it to work), or
package everything into one module (e.g. your WAR could contain everything), or
declare a formal manifest for the WAR module, allowing it to declare the its dependencies on the individual JAR modules, which should allow the WAR to see the resources in the JAR module.
I think there is an easier solution than these 3 skaffman mentioned above.
Put in a module-b.war/WEB-INF/web.xml these lines:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/resources/beans.xml
</param-value>
</context-param>
This enables loading every /resources/beans.xml from any piece of classpath (i.e. any jar on classpath) which is enough for you.
You should load a module-a.jar as a part of a module-b.war (module-a.jar resides in module-b.war/WEB-INF/lib location).
I have very similar granularity in my project: business-logic.jar with its beans' configuration and frontend.war which uses beans configured in previous one via ref="someBean". It works.