Reproduce Eclipse JAR export with javac on Linux - java

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.

Related

Compiling a single .java file in a Maven project

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.

How can I access IntelliJ's java compiler from the command line?

I have a very large maven project, and when I'm debugging, it sucks to have to rebuild the entire project just to see the changes. My current method is to compile the java file in IntelliJ, then copy the class file in my target directory, to my tomcat/webapps/project/ directory, and replace the existing class file with the intellij compiled class file. Then rebuild the war file, and replace it with the existing war file in the tomcat/webapps directory.
I want to be able to automate this process. I looked into doing it with the javac command, but I'm having problems with packages be imported from jar files in the .m2 directory, and can't figure out how to automate the classpath, depending on the specific file. I'm sure IntelliJ does this automatically, and was wondering if there's a way to run IntelliJ's compiler from the command line, or if anyone has any insight into how I can get javac to work for just the one file in my whole project scope.
Any help is appreciate, thanks!
IntelliJ delegates (by default, there are options to delegate to the Eclipse compiler or other ones) to the javac compiler.
If you do not want to import your project into IntelliJ, then you can use maven from the command line to build the project.
If you do not want to build the whole project, then you can use javac from the command line.
To generate your classpath, use :
mvn dependency:build-classpath -Dmdep.outputFile=classpath.txt
classpath.txt will contain your classpath.
From then you can do : javac -cp (contents of classpath.txt) your java file.
IntelliJ is fast even on large maven projects and it can easily compile into an exploded war your tomcat would point to. It is unclear to me on why you would not want to benefit from IntelliJ.

How to add external library to Hadoop map-reduce task

I have MyClass.java to define the map-reduce task. MyClass.java contains the definition of mapper, reducer and main. It works properly, but if I try to use/add an external jar, I have the message ClassNotFoundException.
To compile I use the command:
javac -classpath hadoop_library_path:my_library_path -sourcepath code_path/ -d class_path/ path/MyClass.java
I create the jar, and then I run the task:
hadoop jar maclass.jar MyClass input output -target target
The external jar need to be added also in in "jar hadoop" command?
I tried with the -libjars option with no result. Any idea?
As I commented, I see two options (there could be more):
Use Eclipse and generate a runnable jar (I am not sure about NetBeans or IntelliJ).
Use maven and its shade plugin to generate an uber jar. You should add all the external libraries that you use as dependencies.
I recommend the latter option.

How to use code libraries from github?

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

Javapackager: Cannot find or load main class

I have created a JavaFX project and am able to run it with the command
java -classpath [very-long-list-of-class-paths] danIDE.Main
However, when I try to use javapackager to create a jar out of it and run with java -jar out.jar, the prompt says Error: Could not find or load main class danIDE.Main
The command I used to create the jar is
javapackager -createjar -v -classpath [very-long-list-of-class-paths] -srcdir src -outfile out -appclass danIDE.Main
I have googled for a long time on this problem and I still couldn't find the solution. Can someone point me to the right direction? Thanks a lot!
Edit:
Here is the project structure.
and here is the exploded jar.
New exploded jar as #Garry requested:
Since you're using IntelliJ IDEA I suggest you let IDEA create your JAR file for you.
First, open up the module settings window:
Then, add a new artifact:
Select JAR From modules with dependencies:
Select your main class in the window and decide if you want to repackage all classes from your dependency JARs in your JAR (extract to target JAR option) or if you want to distribute them alongside your JAR (copy to the output directory and link via manifest option):
If you want to build it whenever you build the project (probably a good idea), click the checkbox for that:
When you next Make the project, the JAR will show up under out/artifacts:
If you didn't click the checkbox for building the JAR when you build the project you can build the JAR from the Build Artifacts option in the Build menu.
Can you try using below command? Make sure to update 'classes' folder to the Base directory of the files to package.
As you said in question that you are able to run danIDE.Main so I assume all the required classes are available in dist folder.
So create a folder out in the project parallel to dist
javapackager -createjar -classpath [very-long-list-of-class-paths] -appclass danIDE.Main -srcdir dist -outdir out -outfile out.jar -v
Updated: as per the uploaded screenshot: point -srcdir to dist, now the generated jar out.jar will be placed in out/out.jar

Categories

Resources