I have a Java webapp (WAR) that has several dependencies. Two of them contain resources to be exposed in the war (with the same name).
So my dependency tree looks like
The my issue is that the custom.css from the core.jar dependency is used if I access index.html
Is there a way to force the usage of the custom.css? I cannot modify core.jar
Thanks,
michael
Environment: Maven 3, Java 1.8, Tomcat 8
There's no guarantee as to the relative ordering of JAR files in WEB-INF/lib, but it is guaranteed that WEB-INF/classes will be ahead of all the WEB-INF/lib/*.jar files in the classpath. So if you can get the right custom.css into WEB-INF/classes/META-INF/resources in your final WAR file it will be used in preference to the ones in the lib JARs by ClassLoader.getResource.
You can extract and put necessary resources into myWAR itself.
As long as it's loaded by classloader (which is likely in your case) you're guarantied to not be able to force ordering.
You might be able to unpack the core.jar dependency and exclude the custom.css file as for example specified in Building a WAR project with unzipped JAR dependency?
In such case, you would exclude the core.jar dependency in maven-war-plugin (see https://maven.apache.org/plugins/maven-war-plugin/examples/including-excluding-files-from-war.html) and configure maven-dependency-plugin to unpack core.jar to target/classes while excluding META-INF/resources/custom.css.
Related
In my Maven project , I have certain dependencies which should be present inside the WEB-INF/lib . I cannot put all the jars inside WEB-INF/lib , only the selected ones . How to go about doing this?
I cannot use the maven-resources plugin since then I would have to mention the entire jar's name inside <include> tag and I need to keep it dynamic.
I tried using <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes> but this not give me an option to insert only selected jars inside the lib folder.
I also tried using <scope>provided</scope> for some of the jars but due to this the name of the jar doesn't get added to the classpath field inside manifest.mf file.
Please suggest some solution. Thanks in advance!
You can use Assembly plugin and customized assembly descriptor. In descriptor you can set which jars you want to copy with their artifact id, group id, version and scope. it also supports regex. https://maven.apache.org/plugins/maven-assembly-plugin/advanced-descriptor-topics.html
This may not be the best way to package the content for the WEB-INF/lib/ nested directory in a WAR file, but the implementation presented in the question for How to put all required jars in a lib folder inside the final jar with maven (using the maven-dependency-plugin plugin) solved my JAR needs for bundling all dependent jars into the lib/ directory of my final jar. Oddly it's a commonly asked question, with many different solutions. This implementation actually bundled the jars inside the nested lib/ directory, while others, for example, extracted the contents of my dependent jars and laid their classes beside my classes. So this might get you a little closer but probably not the official way of handling a WAR files' library deps.
I'm working with Maven and Tomcat. Some of the web applications I have to deploy use a lot of dependencies that are marked as "provided" in Maven. One example of these dependencies is spring-context.
So, when I package the project, those dependencies are not included in the lib folder of the WAR file.
Because of this, I'm getting
NoClassDefFoundError: org/springframework/context/ApplicationContext
I can't change the scope of the dependencies, and if possible, I don't want to include the dependencies JARs in the WAR file.
How can I add the Maven repository as a classpath to Tomcat, so it can resolve all the "provided" dependencies? Without copying the JARs to Tomcat's lib folder.
I tried the shared.loader property in catalina.properties, but it doesn't work recursively: I have to add each JAR path to the property's value.
A dependency is marked as provided when the app server or container already has it, and you don't have to put it in the war. This is the case i.e. for the servlets jar, but not for the spring-context. I think the better solution would be to mark this dependencies as "compile" instead of "provided".
You have few options here. Like #Andres said, you either add the JARs in the WAR or you add them to the classpath of Tomcat (ie lib folder).
While the concept of having a Maven-aware classloader is interesting, imagine all the possible jar version conflicts that could occur. War A having a provided dependency on Lib v1.0.1 and War B having a provided dependency on Lib v2.1.0, with Tomcat silently resolving these...
I am using maven build tool.
The following two are my intentions.
1) To move some of the third party library jars out of my war from WEB-INF/lib folder [note: These jars are common between more than 2 war files (or artifacts)]
2) To make the war file small in size.
Is it possible to move those jars out of war and put it into a folder and these jars should be referred in the classpath only by the wars which require it.
I have tried adding the path to the jars in the Class-Path: of MANIFEST.MF of war files but it did not work out. Please help me out.
I assume the jars in question are necessary for compiling the code that make up the web application. If the third-party jars are necessary for compilation but you don't want them in your war file, you have two options:
In the <dependency></dependency> section for the third-party jar, add "<scope>provided</scope>".
Configure the maven war plugin to exclude the jars you don't want in the war. See http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html for the details.
How you get the jar files that you exclude from the war into the web container's classpath depends on your environment. If you are using ear files, the Maven docs above talk about how to get the jars included in the ear file. If you are not using ear files, you will have to come up with your own way to get the jars into the container's lib directory.
As we do in Ant build, we can specify the Jars that we need to copy in build.xml in case of Ant(We just need to specify the folder name from which we need to pick the jar files). Is there any facility of same kind is available in Maven as well.
If yes, Then do we need to add the dependency tags equal to the number of jars in folder or one dependency tag is sufficient. I hope you get my point.
I think your missing the point of dependency management. All the JAR's required by your project should be defined as dependencies in your POM. If you have any custom JAR files (not available in a public repo) then you will want to install those in a local repository, and access them that way.
My goal is pretty simple: to use ant to build an EAR which contains 1 EJB and 1 jar containing all of the dependencies. This jar, called common.jar for the sake of example has vendor jar files in it as well as other xml files that the EJB depends on and will need to be able to see during runtime....
So far I have everything packaged correctly as an EAR like this:
EARFILE.ear
-EJBFILE.jar
/META-INF
-MANIFEST.MF
-common.jar
/META-INF
-MANIFEST.MF
/lib
-(all vendor jars inside here)
-(All the xml config files are inside the root of the common.jar)
Inside the MANIFEST.MF for the EJBFILE.jar is...
Class-path: ../../common.jar
Inside the MANIFEST.MF for the common.jar is...
Class-path: ../lib/some_common.jar
When I deploy this the appserver (websphere) cannot find the JAR file when I try to start the server. I am getting the ClassDefNotFoundError because the classes inside the EJB cant find the vendor JAR files when I try to start the instance. However I know that common.jar is setup correctly though, else the EJB wouldn't have compiled since it needed to have those vendor jars on the classpath for javac.
So what I want to know is this:
How can I get the runtime to correctly see the Vendor jar files.
Will the EJB be able to see the xml files at run-time? I am concerned about this because these xml files are located outside of the EJB inside of a jar that is just in the EAR, it isn't even a module its just a jar inside the EAR.
Does it even matter when using websphere? From what I gather some containers don't even care what is in the Class-path of MANIFEST.MF.
There are several improvements I can suggest, based on running into similar problems.
First and most importantly, use the appxml attribute of the Ant ear task to specify your deployment descriptor (usually named application.xml); also include references to the vendor JAR files bundled as defined below
I would recommend you not put your vendor JAR files into another JAR - instead, just copy them into the EAR at the same level as EJBFILE.jar
The configuration XML files can go in a sub-directory of the EJBFILE.jar (such as config), and then you can reference them as /config/filename.xml.
The application.xml file will tell WebSphere where to find your JAR files. Classpath traversal in an application server is not the same as that of a compiler, which JBoss has taught me the hard way.
I am using all of the above patterns, and my in-container code (deployed in the EAR) can see all my XML files, as well as find all my dependencies.