I have a Spring Boot application that loads zero or more external jars from a known location during startup. Application is started using PropertiesLauncher by executing java -Dloader.path=application.jar,BOOT-INF/lib,jars/ -jar application.jar -XX:PermSize=512m -XX:MaxPermSize=512m. The external jars are built in maven using the MODULE configuration.
These jars primarily contain Spring managed classes such as services and controllers. When this is the case, everything loads as expected. However, if i attempt to load a jar that needs access to the jars in its own internal /lib folder, startup fails with ClassNotFoundException. If i use the fat jar model of bundling these dependencies in application.jar, but i'd prefer not to bloat that jar with library files that may never be used if at all possible. Is it possible to get jars within a jar built as a MODULE onto the classpath where PropertiesLauncher can find them?
Related
I want my project to be launched on my personal computer via the Main function (either via java -jar or by mvn spring-boot: run), and when the development is complete, I can deploy it directly to Tomcat.
How to configure, to do this
You don't have to do anything special. Just follow the official documentation to build a deployable war. The war file created using the Spring Boot build process is executable as a regular jar file as it contains an embedded servlet container in a separate directory called lib-provided which is added to the classpath only when the war is directly executed.
Bonus: If you want to get rid of unnecessary dependencies on embedded server when creating a deployable war, you can check out a blog post, which show how to do it step-by-step.
I want to build a runnable jar for a JavaFX application which uses depency injection (Spring framework libraries) to manage multiple FXMl files and multiple FXMLDocumentControllers.
However, when exeuting the jar a "ClassNotFoundException: org.springframework.context.annotation.AnnotationConfigApplicationContext" is reported.
Yet, I have added Spring library (3.2.7) to the project in Netbeans and it functions well within the IDE.
How can I assure, that the above class is available in the jar as well?
When compiling and packaging your code, the resulting jar usually only contains YOUR code. You need to add the dependent jar files to the classpath. What that means is, whenever you invoke java -jar yourapp.jar some.package.MainClass to run your application, you need to list all required jar files in the -cp option of the java command.
Another (bad) solution could be to use maven's assembly plugin (or some other means) to create a fat-jar, which essentially is a merge of yourapp.jar and all dependent jars.
Read: Building a fat jar using maven
could you please explain the difference in addng jars in lib folder and adding jars to classpath .
are both just a way to add jars(anyone will work) or is there any difference ?
I tried searching but couldn't find any answer.
If you have a web application project that bundles into a WAR, then adding the jar files into WEB-INF/lib will automatically put all these jar in the classpath of the application when being deployed in a servlet container (Jetty, Tomcat) or in an application server (GlassFish, Wildfly). Note that these libraries will only be available for your single application being deployed, not for any other app deployed in this server.
If you have a simple jar with a lib folder inside it, then adding any jar into this folder will do nothing. For jar files that must be executed on their own, you need to specify the libraries to use in the classpath, otherwise your jar will not run. For this case, it will be better to have the libraries inside a lib filder outside the jar, so you could reference them in the MANIFEST file. On the other hand, you may use maven to generate a fat jar.
If you are using any third party jar files then you need to add it in classpath because you java application tries to find out the class which you are using in you app.
Adding jars in classpath means you are explicitly adding the jar files in classpath at the time of execution.
Adding jars in lib folder will be done in eclipse will internally add the jar files in classpath at the time of execution.
To verify both the things execute the following command
ps -eaf | grep -i java
which will display your app with the dependencies(jar files) in classpath.
I am trying to tackle a persistent ClassNotFoundException. We have an application specific jar that calls a shared commons jar, and uses reflection create an object that we specify in an XML file. This is where it fails.
The application specific jar resides in my NSF. The commons jar resides on the server. I wish to keep the jars in the NSF, because I will be replacing them frequently and don't have access to the server directories, even in Unit.
We put the application jar in the same package as the commons and this didn't help. My suspicion is that the server jar cannot find the application jar. The application jar successfully calls the commons jar, so it is working in that direction.
I tried putting a copy of the commons jar in the NSF, and this didn't help. I think it is still running the server jar first. Jars have same name.
My question is: How do I force the Domino Server runtime to use the application's 'commons' jar instead of the server's 'commons' jar? The thinking being that the local commons jar will find the class of the application jar in the same package, and I can get past this exception.
UPDATE: This process runs when run from a jUnit test, and when a main method is created.
The key is going to be identifying if it's failing because of a security exception or just not finding the jar. If it hits a security exception loading the jar, it just gives that ClassNotFoundException. That can be because it's using the same ClassLoader as the XPpages runtime and was the problem I hit with apache.commons.lang.
If a jar is likely to change regularly and you want it from multiple NSFs, but don't have access to the server, the best option is to create an OSGi plugin (aka Extension Library). This will overcome most security exceptions as well as using a different classloader.
Put it in WebContent\lib, then right-click on it and choose Build Path > Add to Build Path. It will then use a different ClassLoader. See the comments on this blog post http://www.intec.co.uk/how-to-add-in-built-java-packages/. The lib folder is added by default in R9. You do need to add it to the build path, then it jumps into a Referenced Libraries folder.
I noticed that WAR files are supposed to have classes/ and lib/ directories for containing their classfile root and dependencies, respectively.
I also noticed that it is not common practice for JARs to contain such a lib/ directory and to contain their own dependencies.
So now I'm wondering why JARs shouldn't/usually-don't contain their own dependencies, but WAR files are expected to. Unless I'm missing something, both require their dependencies to be on the classpath at runtime (JARs won't run if they're missing dependencies, just like WARs won't run). So to me, all the arguments for putting dependencies in a WAR file also apply to a JAR.
What am I not "getting" here?!?
From a conceptual point of view:
A jar typically represents a single library which can be used and may or may not have dependencies.
But the idea is that a specific functionality can be provided as a library in a jar.
A war is an application by itself and as such it should include all the dependencies
WAR files (mainly WEB applications) are uncompressed, and all JAR files inside the lib folder will be in the classpath of your web application while running.
JAR files might also contain jar files, but will not be found and loaded by the default class loader.
There are special class loaders that do load jar files inside jar files, but not standard.
Because unless you use a custom classloader that can load classes from nested jars (like JarClassLoader), you can't load classes from nested jars. Servlet and app containers will add jars contained inside war/ear files to their application's classpath.
They are containers with different purposes.
Jar is intended for Java class files and resources and can be a library or a directly runnable application.
War is a container to package complete Web applications including all dependencies (such as Jar files and other web resources).
The question boils down to, why can't a jar include other jars. This I would take as a design decision taken to allow maximum flexibility in interchanging dependencies.