Add jar file to spring-boot classpath at runtime - plugins

I want develop a modular application using spring-boot and plugins. The plugins will be handled with spring-plugin and these are stored in jars files in a directory (for example: /home/application/plugins).How can I add jars files to the application classpath at runtime and loading classes and beans (plugins) that are in these jars files.
Best regards, HLicea

You need to use PropertiesLauncher instead of JarLauncher:
java -cp "yourBoot.jar" -Dloader.path=plugins/ -Dloader.main=your.mainClass org.springframework.boot.loader.PropertiesLauncher
This will make java load the jars in the plugins directory and spring load all the classes in those jars marked as #Configuration into the context.

I believe "standard" java approach should work here, e.g. for Linux:
java -cp "yourBoot.jar:plugins/*" org.springframework.boot.loader.JarLauncher
Only trick is that I have taken Main-Class from boot's uberjar.

Related

Helidon override libs folder

Is it possible to override the libs folder in helidon project? I want to copy jars to classpath at runtime. I was able to use -Dweblogic.ext.dirs to do that in weblogic server.
Helidon isn't an application server, so it just works with the regular Java classpath. As with any Java program, once the classpath is set, it's set. Helidon does not use multiple classloaders, so there's no runtime deploying or anything like that. (You are, of course, free to create your own classloaders or whatever you want since it's just Java.)
So: set up your classpath the way you want, and start your Java program that uses Helidon libraries.

Eclipse: Debug war in ear when the war-file only is a maven-dependency instead of an eclipse project

We have the following packaging:
something.ear (eclipse-project)
+webstuff.war (maven dependency only)
+businessstuff.ejb (eclipse-project)
Packaging works perfectly and I am able to debug all the businessstuff. But how can I make the sourcecode of webstuff.war visible in eclipse and therefore set brakepoints and debug it?
ear and war have only java class files(which is not editable) and not java source code. Better approach is to use some logging framework(i personally prefer log4j).
Every java project developed nowadays have used some logging framework, better search for them in the ear and war files.
On extracting the war file u can see some xml or .properties file which will say what loggong framework it uses.

Deployment Concepts: Packaging JAR Dependencies, When & Why

So I'm relatively new to Java EE and I am having a tough time understanding when, where and why Java deployment files are packaged with their dependencies.
Say I build my project into myapp.jar, and it depends on fizz.jar, buzz.jar and JODA (joda-time-2.0.jar).
I've heard that the default classloader doesn't package jars inside of other jars, so I have to assume that if I called a jar task from Ant, then the default classloader would get invoked and myapp.jar would be created without those 3 dependencies in it.
Is this because the mentality is to deploy main-less jars in containers or other systems that will provide its requirements at runtime? If not, then how does myapp.jar ever run correctly?
What about executable jars? To met, these must be different than main-less jars, because they are meant to be standalone units, right? That means they would need all of their dependencies packaged with them, right?
Last but not least, what about jars that depend on jars that depend on jars...etc. (i.e., dependencygraphs that are huge)?
I guess all of these questions can be summed up as follows:
Is the idea behind a non-executable jar that it will be ran in such a way that it will know what classpath(s) to look on for its dependencies at runtime? (And thus doesn't need to be packaged with its dependencies)?
Is the idea behind an executable jar that it is a standalone unit and should be pacakged with its dependencies?
If my assertion to Question #1 above is correct, how does such classpath configuration take place? Are these settings that are stored inside the jar (such as in the manifest)? Else, how would a JRE know where to search for a particular jars dependencies at runtime?
Answers to these questions will actually clarify quite a lot of hangups I have with Java fundamentals, and so any input/help here will be appreciated enormously! Thanks
Jars do not know about other jars (unless assisted by some tools like Maven). The inter dependency of the jars is purely resolved by the Classloaders. I strongly recommend to have some idea about classloaders.
To address your questions,
Is the idea behind a non-executable jar that it will be ran in such a way that it will know what classpath(s) to look on for its dependencies at runtime? (And thus doesn't need to be packaged with its dependencies)?
NO. As mentioned, it's the classloader which looks the classpath and the jars mentioned therein. The jars do not have any information about other jars.
Is the idea behind an executable jar that it is a standalone unit and should be packaged with its dependencies?
NO. A classloader loads the standalone executable jars at the start of execution. If it needs other dependency jars it'll look into the classpath for those jars.
If my assertion to Question #1 above is correct, how does such classpath configuration take place? Are these settings that are stored inside the jar (such as in the manifest)? Else, how would a JRE know where to search for a particular jars dependencies at runtime?
For standalone jar (executable jar), the classloader looks for the classpath variable OR classpath passed while invoking the application.
For other type of application (WAR, EAR), There are predefined places/folders where the dependencies should be placed in order to get picked up. This is standardized by specs.
In a nutshell, it's the classloader which is pulling all the threads. There is standard places where it looks for all the dependent jars. This link nicely describes how the classloaders in standalone application and in a deployed (in some container) works.
JAR files are a way to package togher complex java application. Jar application are easy to move between diffrent machines and operating system.
I think the right way to use Jars is not tu put everything (every dependencies) into a single jar.
For example if your application uses a jar libryra (for example jdbc) to access a database you should not put the jdbc jar into your jar.
You had better to build a jar file with only your .class file.
Of course your code needs the jdbc jar to work properly. Here comes to explain how the virtual machine searches for extarnal classes:
-it first searches in the directories that contain the classes that come standard with J2SE (the path depends on your installation)
-it searches in the directories specified by the classpath (a classpath is either an environment variable or an option of the java command)
for example:
java -jar -c /your/path/ yourApp.jar
will run your application and will search th classes your application refers to in the directory /your/path/ so if you have external jars you can put them in that directory.
For detailed documentation: http://download.oracle.com/javase/tutorial/deployment/jar/index.html

How to add JAR libraries to WAR project without facing java.lang.ClassNotFoundException? Classpath vs Build Path vs /WEB-INF/lib

How should I add JAR libraries to a WAR project in Eclipse without facing java.lang.ClassNotFoundException or java.lang.NoClassDefFoundError?
The CLASSPATH environment variable does not seem to work. In some cases we add JAR files to the Build Path property of Eclipse project to make the code compile. We sometimes need to put JAR files inside /WEB-INF/lib folder of the Java EE web application to make the code to run on classes inside that JAR.
I do not exactly understand why CLASSPATH does not work and in which cases we should add JARs to Build Path and when exactly those JARs should be placed in /WEB-INF/lib.
The CLASSPATH environment variable is only used by the java.exe command and even then only when the command is invoked without any of the -cp, -classpath, -jar arguments. The CLASSPATH environment variable is ignored by IDEs like Eclipse, Netbeans and IDEA. See also java.lang.ClassNotFoundException in spite of using CLASSPATH environment variable.
The Build Path is only for libraries which are required to get the project's code to compile. Manually placing JAR in /WEB-INF/lib, or setting the Deployment Assembly, or letting an external build system like Maven place the <dependency> as JAR in /WEB-INF/lib of produced WAR during the build, is only for libraries which are required to get the code to deploy and run on the target environment too. Do note that you're not supposed to create subfolders in /WEB-INF/lib. The JARs have to be placed in the root.
Some libraries are already provided by the target JEE server or servletcontainer, such as JSP, Servlet, EL, etc. So you do not need put JARs of those libraries in /WEB-INF/lib. Moreover, it would only cause classloading trouble. It's sufficient to (indirectly) specify them in Build Path only. In Eclipse, you normally do that by setting the Targeted Runtime accordingly. It will automatically end up in Build Path. You do not need to manually add them to Build Path. See also How do I import the javax.servlet / jakarta.servlet API in my Eclipse project?
Other libraries, usually 3rd party ones like Apache Commons, JDBC drivers and JEE libraries which are not provided by the target servletcontainer (e.g. Tomcat doesn't support many JEE libraries out the box such as JSF, JSTL, CDI, JPA, EJB, etc), need to end up in /WEB-INF/lib. You can just copy and paste the physical JAR files in there. You do not necessarily need to specify it in Build Path. Only perhaps when you already have it as User Library, but you should then use Deployment assembly setting for this instead. See also ClassNotFoundException when using User Libraries in Eclipse build path.
In case you're using Maven, then you need to make absolutely sure that you mark libraries as <scope>provided</scope> if those are already provided by the target runtime, such as JEE, Servlet, EL, etc in case you deploy to WildFly, TomEE, etc. This way they won't end up in /WEB-INF/lib of produced WAR (and potentially cause conflicts with server-bundled libraries), but they will end up in Eclipse's Build Path (and get the project's code to compile). See also How to properly install and configure JSF libraries via Maven?
Those JARs in the build path are referenced for the build (compile) process only. If you export your Web Application they are not included in the final WAR (give it a try).
If you need the JARs at runtime you must place them in WEB-INF/lib or the server classpath. Placing your JARs in the server classpath does only make sense if several WARs share a common code base and have the need to access shared objects (e.g. a Singleton).
If you are using Maven:
Open the project properties, and under Deployment Assembly click Add...
Then select Java Build Path Entries and select Maven Dependencies
Resolved by setting permissions.
Had related issue using PySpark and Oracle jdbc. The error does not state that the file cannot be accessed, just that the class cannot be loaded.
So if anyone still struggles, check the permissions. Some might find it obvious tho'.
I want to give the answer for the folowing link question ClassNotFoundException oracle.jdbc.driver.OracleDriver only in servlet, using Eclipse
Ans: In Myeclipse go to Server-->left click on Myeclipse Tomcat7-->Configure Server Connector-->(Expand)Myeclipse Tomcat7--> Paths-->Prepend to classpath-->Add jar (add oracle14 jar)-->ok

How to include external jar in ejb-jar

How can I include external jar file in my ejb3 jar file? There is one external jar project with all helper classes and manifest.mf file. Now I have this jar in my classpath in eclipse. But when eclipse build the ejb-jar I want it to include this external jar file so in Application server when my ejb loads and run it can use classes in external jar. Right now I am adding a reference in Manifest.mf for ejb-jar, still when eclipse build the ejb-jar it is not packaging this external jar and during runtime I am getting ClassNotFoundException.
Can somebody please give me an example how to achieve this? I am using Eclipse 3.6 and EJB3
You have to create ear or war deployment and include your ejb.jar and a third-party.jar into it. Then deploy it to jboss
I found a solution.
Method 2 Worked for me. the tutorial uses Rational, but I assume Eclipse will be similar.
http://www.ibm.com/developerworks/rational/library/07/1211_schrag/index.html
check it out.