Right now, am using mvn package exec:java -DskipTests, which will compile my project just fine, and start a server.
Instead of restarting the server, if a .java file changes, would like to only re-compiling that lone .java file.
Does anyone have a reliable javac command that can compile a single .java file in a Maven project, and put it in target/classes?
Here is the project structure:
src/
main/
java/
foo/
My.java
and then it needs to be compiled to this location:
target/
classes/
foo/
My.class
the following bash script will compile the file if it has no imports.
#!/usr/bin/env bash
mkdir -p "$PWD/target/classes/foo";
javac "$PWD/src/main/java/foo/My.java" -d "$PWD/target/classes" -cp "$PWD/src/main/java"
but if I include imports in the file, then I need to use a classpath which includes the maven dependencies.
So when I set the classpath using -cp, I need to do something like:
-cp "$PWD/src/main/java:$M2_HOME"
does anyone know what I should add to the classpath to cover the maven deps necessary for a maven project?
Update
The only way I think this would work, is if Maven could bundle all the dependencies used in the first real build into one jar file, in a deterministic location. Then if I wanted to compile a single java file, I would reference that jar in the classpath.
Otherwise, it appears that maven append 100s of paths to the CLASSPATH, and has to do some careful calculation to figure out which version of which jar to include the CLASSPATH. It would likely be impossible to be sure which jars were included in the original build. So the only way to know would be for Maven to spit out a new jar of all the library deps in one jar file.
Related
I am having an executable JAR. Ofcouser I have JDK installed at my end I am giving following command to run my exe JAR from command prompt.
1 Using JRE :-
C:\Users\userName\Desktop\Utility\latest>"C:\Program Files\Java\jre1.8.0_161\bin\java.exe" -jar Utility.jar
2 Using JDK
C:\Users\userName\Desktop\Utility\latest>"C:\Program Files\Java\jdk1.8.0_161\bin\javaw.exe" -jar Utility.jar
Both are working on my desktop but if I tries #1 to run the executable JAR on different machine which has only JRE Version (1.8 onwards) it is not getting opened up.
I tried following links but some links are sayin to download few installers but all I do not want to get that. Is there any way. Or issue with my executable JAR ?
How can I make my executable JAR not need JDK to run
Run a JAR file using a specific JRE
Manifest-Version: 1.0
Rsrc-Class-Path: ./ commons-collections4-4.3.jar poi-3.17.jar poi-ooxm
l-3.17.jar xmlbeans-3.0.1.jar curvesapi-1.06.jar poi-ooxml-schemas-3.
17.jar poi-examples-3.17.jar poi-excelant-3.17.jar poi-scratchpad-3.1
7.jar commons-codec-1.10.jar commons-collections4-4.1.jar commons-log
ging-1.2.jar curvesapi-1.04.jar junit-4.12.jar log4j-1.2.17.jar xmlbe
ans-2.6.0.jar ooxml-schemas-1.3.jar
Class-Path: ./ commons-collections4-4.3.jar poi-3.17.jar poi-ooxml-3.17.jar
xmlbeans-3.0.1.jar curvesapi-1.06.jar poi-ooxml-schemas-3.17.jar poi-examples-3.17.
jar poi-excelant-3.17.jar poi-scratchpad-3.17.jar commons-codec-1.10.jar
commons-collections4-4.1.jar commons-logging-1.2.jar curvesapi-1.04.jar
junit-4.12.jar log4j-1.2.17.jar xmlbeans-2.6.0.jar ooxml-schemas-1.3.jar
Rsrc-Main-Class: DataProcessor.DataProcessor.App
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoade
It sounds like the issue your are having is more than not having the JDK or knowing where the JRE on the target system is located, it's that you also didn't include the dependencies that your code has.
The jar file you have includes details in the manifest file that tells the JVM the classpath and the main class to load. If you look at the Rsrc-Class-Path, it is add the jars from the current directory. This is fine if you are sending the entire folder structure that includes all the jars in the expected location. But it doesn't work with just the jar.
In order to make a single jar that would run without any additional jars, you need to repackage the jars. There are two common ways to do this
UberJar - where the class of your project is combined with the classes extracted form all of your dependencies into a single jar
JarInJar - where your jar and all the dependecy jars are put into a jar and a custom classloader is used to load the classes from the jars inside the jar.
I'm not sure what build tool you're using, but for Maven the Shade Plugin will create an UberJar.
I personally recommend using the JarInJar option for this reason. The Spring Boot Maven Plugin is what I believe to the easiest
In my project I have this code that tell class loader to load Driver.class like so:
Class.forName(org.gjt.mm.mysql.Driver);
In Eclipse it runs with no problems and I have created the Jar file of the project. But I don't know how to insert the
mysql-connector-java-5.1.7-bin.jar
into a Jar file of my project. The folder structure look like this:
MANIFEST file:
Manifest-Version: 1.0
Main-Class: server.MultiServer
I am assuming that you finally just want to run your code as
java -jar myjar.jar
There are two options.
Keep mysql-connector-java-5.1.7-bin.jar next to your jar in the same folder and add classpath: mysql-connector-java-5.1.7-bin.jar to the manifest.
Copy all the classes in mysql-connector-java-5.1.7-bin.jar to your jar. Do not copy the jar but the classes in the jar. This is called a fat jar or uber jar. You can automate the same using maven shade plugin.
When you invoke your application jar add the -cp or -classpath option and provide the path to the dependent libraries, here the mysql-connector-java-5.1.7-bin.jar.
for example refer the below example
java -jar -classpath C:\myproject\lib\mysql-connector-java-5.1.7-bin.jar myproject.jar
The structure of my first app is simple:
libs
opencsv-3.8.jar
yamlbeans-1.0.jar
out
artifacts
...
production
...
src
META-INF
MANIFEST.MF
pl.krzysiu
App.java
CsvReplacer.java
Everything is fine during the compile and running the program. After building artifact jar file in the default out\artifacts directory, I get
java.lang.NoClassDefFoundError: net/sourceforge/yamlbeans/YamlException
when I try to run it by java -jar CsvReplacer.jar command
The libraries are included inside the jar file (they are there after unpacking it) - they are added to Libraries section in Project Structure (separately - one file per one lib), the whole libs dir is included in the Dependencies tab of Modules section (with export checkbox checked) and the libs dir is added in Output Layout of Artifacts section similarily.
The manifest file contains:
Manifest-Version: 1.0
Class-Path: libs\yamlbeans-1.0.jar libs\opencsv-3.8.jar
Main-Class: pl.krzysiu.App
Why the libs aren't visible for the App? If I copy this dir manually to the CsvReplacer.jar file's location - everything works fine.
The structure inside CsvReplacer.jar file looks like:
libs
opencsv-3.8.jar
yamlbeans-1.0.jar
META-INF
MANIFEST.MF
pl
krzysiu
App.java
CsvReplacer.java
IDE: Intellij IDEA 2016.3
The standard Java classloaders cannot find a JAR file embedded inside another JAR file.
You have two choices when making an executable JAR with dependencies.
Create a so-called uberJAR file by merging the contents of the dependent JARs into your main JAR.
References:
IntelliJ IDEA export Runnable program as Uber Jar
https://blog.jetbrains.com/idea/2010/08/quickly-create-jar-artifact/
Give your JAR a "Class-Path" manifest attribute to tell it where the (external!) dependent JARs are located.
You can't give a -cp and a -jar option together. But another alternative would be to get rid of the -jar option and use a -cp argument to specify the classpath.
Alternatively, you could implement a custom classloader that can load from a jar inside a jar, or use something like one-jar or Spring Boot.
I need some tools to read JSON from a URL. However, when I tried to use the JSONObject class, it was unavailable. I looked it up and it was suggested that I should download the required library : https://github.com/douglascrockford/JSON-java
I'm unfamiliar with downloading and creating a jar of Github repositories. I have downloaded the repository in zip fromat. ( I am using windows 8). I navigated to the location, extracted the files and tried to create a jar.
I found half of the solution in : How to make this (github) source into a library/jar?
Based on the Suggestion i used the command to make jar:
git clone git://github.com/douglascrockford/JSON-java
cd JSON-java
jar cf JSON-java.jar *.java
I got a jar generated in the folder, I dragged it over to the library folder in my eclipse project.
However, I still don't find any of the required classes available while coding.
Additionally, I tried compiling the code >javac *.java and then tried the jar creation step but no avail.
What steps I missed?
When you have to attach external library in Java, generally you should have jar with compiled sources.
What we have in repository is source code, nothing more, so you can't just pack it and get compiled files (*.class).
So, your options here are at least so:
Download compiled jar, provided by author and attach it to the project within Eclipse (How to import a jar in Eclipse)
Use maven project, for which you can define dependency on some external project: http://mvnrepository.com/artifact/org.json/json/20140107
Compile the project yourself (not recommended): in Frederic Henri's answer
not sure what you mean with the compilation of java file and "no avail"
but you need to compile java files before you package them as jar :
mkdir build
javac -d build/ *.java
then package the build directory as jar
jar cf JSON-java.jar -C build/ .
then import the jar file in your library of the project - make sure to add it in your eclipse lib settings and you should be able to reference the org.json package
I need to be able to reproduce the following Eclipse process:
Export
Runnable JAR file with option "Extract required libraries into generated JAR"
This results in a JAR that includes all the referenced libraries and they have been compiled.
However, when I use this command on Linux:
javac -cp lib/lib1.jar:lib/lib2.jar -d newJAR src/Main.java
I get a JAR that includes just the class files of my own code.
I need to find a command that could produce the same output as with Eclipse, on the Linux command-line.
What you are asking for here is non-trivial. You want to package all dependencies into the JAR and also have the class path set so that you can run a class from the new JAR.
Two plugins I have used in the past to do this are maven-assembly-plugin and oneJar plugin.