I have a system where modules are build and deployed into a system. All jars are located under lib folder in that system. My jar has a dependency to commons-io of version 2.0 and other module has dependency to commons-io, too but of version 1.1. So, both versions are deployed to lib folder. There is a method that exists in 2.0 but not in 1.1. When I ran my own jar, it goes and picks old version which is 1.1 ,and it causes NoSuchMethodError. I am using maven. Is there a way to force my module to use the version that I set in pom.xml? I cannot ask other module maintainer for a version change as this lib comes as 4th level transitive dependency.
If you have two different versions of the same JAR in the lib folder and load the whole lib folder onto the classpath, then you are playing roulette.
The JVM may pick one or the other version, and while in theory, you probably can figure out the rules, in practise, it is just unstable.
So, what can you do? Some alternatives:
Remove the version 1.1 from the lib folder and see whether the other module runs with 2.0 as well (often, version upgrades are more or less compatible)
Use two different lib folders, or construct the classpath manually for the two JARs. Only possible if they do not run in the same JVM.
Use the maven shade plugin to shade the required library into your own JAR.
Most of commons-io is obsolete by now because adequate classes/methods are already part of the JDK (from Java 8 upwards). So you might just be able to remove commons-io from your project and do the file handling with Java itself.
Related
I am running a web application using Tomcat, JDK8 and Netbeans IDE (using ANT for build and IVY for dependency management).
I currently place JARs that need to be available to the JRE (servlet-api.jar, jsp-api.jar, el-api.jar, tomcat-dbcp.jar) in JAVA_HOME/jre/lib/ext.
I'm upgrading to a new JDK version (JDK17), which no longer has the JRE extensions folder. I'm wondering where I should place these JARs.
According to this post (and others I've seen), it is better practice to use a dependency manager and add these jars to your classpath anyway.
I currently use IVY to manage my dependencies and have customized my ANT build to add run-time dependencies to the WEB-INF/lib folder of the built WAR file.
However, I do not need the JARs I listed above to be available to my application at runtime, I need them to be available to the JRE. That is, I do not want the JARs (servlet-api.jar, etc.) to be in WEB-INF/lib of my built WAR file.
How can I do this?
Sharpening my final questions:
How can I make certain JARs/dependencies available to the JRE in Netbeans in my development environment?
How can I make certain JARs/dependencies available to the JRE in the built WAR file used on my production environment?
Am I correct in saying that these JARs need to be available to the JRE? All of the posts I've seen discuss compile-time vs run-time dependencies but it seems the case I'm describing is a different category of dependency. Is this correct?
I currently place JARs that need to be available to the JRE (servlet-api.jar, jsp-api.jar, el-api.jar, tomcat-dbcp.jar) in JAVA_HOME/jre/lib/ext.
That's not the best way to do things. See Is putting external jars in the JAVA_HOME/lib/ext directory a bad thing?
Note that the jre/lib/ext mechanism has been removed from newer versions of Java, so this will not work anymore if you use a newer version of Java. (This has been removed in JDK 9).
However, I do not need the JARs I listed above to be available to my application at runtime, I need them to be available to the JRE.
Why?
That is, I do not want the JARs (servlet-api.jar, etc.) to be in WEB-INF/lib of my built WAR file. How can I do this?
Why not? Putting the dependencies that your application needs in WEB-INF/lib is the normal thing to do in Java web applications. Why do you want to do things the non-standard way?
But: Some JAR files, such as servlet-api.jar, jsp-api.jar and el-api.jar are not supposed to be included in your application. Those JAR files define standard Java EE / Jakarta EE APIs and will be provided to your application at runtime by the application server (Tomcat, etc.) that you deploy your WAR file in.
You can add those JAR files as dependencies using Maven with provided scope, which means they will be used while compiling, but won't be packaged into your application.
Am I correct in saying that these JARs need to be available to the JRE?
No, those JARs do not need to be available to the JRE. JAR files that contain standard APIs will be provided by your Java EE / Jakarta EE container at runtime. Other JAR files should be included in your application in WEB-INF/lib.
I have a Java application for which I'm using PDFBox; the latest stable release of PDFBox is 2.0.25. I want to step through PDFBox code after my project calls it.
I have downloaded the PDFBox source, imported it as a Maven project into an eclipse workspace, and put that project on the build path for the application project. I removed the PDFBox dependency from the pom.xml for my application, and did Maven update and clean rebuild for things.
However, another part of my application uses POI, and it also depends on PDFBox, specifically 2.0.24. So the PDFBox 2.0.24 jar is in the 'referenced libraries' for the application, and I've verified that sometimes, when a PDFBox reference is made, it uses the 2.0.24 from the referenced libraries instead of my local 2.0.25 library.
Obviously in strict classpath terms this is problematic -- a classloader will run down the list of available full pathnames until it finds one, and it isn't evaluating library versions. I know this can theoretically be done, on a runtime level, with classloaders, but don't know how to apply that in my situation. How can this get resolved correctly in the general case? The general case wouldn't have to be a debugging situation, it could be 2 (or more) libraries attempting to use different versions of a common library just to get their work done.
In my current situation, I've tried putting a PDFBox dependency before the POI dependency in the dependency list in the pom.xml. I don't know any other way to influence which jar the runtime might use. Is there some way to specify that the POI code use a different classloader or something?
I would like to execute uncompiled groovy scripts with the java jre. I would like to provide just one jar file to do this. I think in older groovy versions this was possible with a groovy-all jar.
e.g. java -cp lib/groovy-all-2.4.6.jar;. groovy.ui.Main myscript.groovy
But this groovy all jar does not exist for new groovy versions. Is there another jar to do that?
I found the gradle-groovy-all project in this thread. This works fine for me. With the newest commit on the master branch the dependency org.apache.ivy is incuded in the built jar.
There are many groovy-$something artifacts (sql, json, ...) and
all was just the combined jar with all of them in it in the 2.4 days.
Now the "-all" is only deployed as Bill Of Materials, that itself no longer
is/contains a jar, but points to all other groovy-$something artifacts itself as transitive deps.
So using "groovy.jar" and "groovy-(a|b|c).jar" might be a way out for you and this all boils down to one jar, if you don't need anything else but groovy.jar.
Or you could roll your own "all" jar (e.g. build a uber-/fat/shadow-jar
in a project with all deps you need (e.g. groovy-all and whatnot).
I was playing with JAXWS 2.2.7 on Java 1.6, so I needed to upgrade the API by adding jars to the jre/lib/endorsed directory as per this documentation.
This worked fine, but after some consideration, I decided to roll back to the older version of the API by removing the libs from the endorsed directory. But this left me with the following error on all of my projects.
The container 'JRE System Library [JavaSE-1.6]' references non existing library '/usr/java/jdk1.6.0_21/jre/lib/endorsed/jaxws-api.jar'
Clearly eclipse added some kind of meta-data that references the jar file, but wasn't smart enough to remove the meta-data property when we removed the JAR file.
I've searched in vain for this meta-data in the project directory and in the eclipse install directory. Can anyone help?
These are my platform details:
Eclipse Juno Build id: 20120614-1722
Fedora 15
jdk1.6.0_21
We have a legacy system that was just ported to AppEngine. So now we need to use Objectify4, however the legacy application we have is not yet "mavenized" so we add jars manually. What are all the jarts needed to be placed in WEB-INF/lib folder so Objectify jars and its depenedencies will work.
The current AppEngine version we set in the classpath is 1.7.2
You can download the builds from the Maven repo here:
https://objectify-appengine.googlecode.com/svn/maven/com/googlecode/objectify/objectify/
That being said, there doesn't appear to be any guarantee with these files so use at your own discretion.
Depending on when how soon you plan to deploy your product, it may make more sense to build your service using v3 as opposed to v4 for now.
Quoting from Objectify documentation:
Add objectify-N.N.N.jar to your project's WEB-INF/lib directory. There are no other jar dependencies.
Edit: The jars are located in the Maven Repository, by browsing the source. For example, here you can find the objectify-4.0a4.jar.
Hope this helps!