OSX-Terminal -jar run command - java

I used to work with Eclipse but switched recently to CodeRunner. The Problem is I'm supposed to use Graphviz, Batik and a Package from my college in order to work on some projects.
As long as there was one .jar file I'll managed to use my own with a simple:
RunCommand: java -jar stopndrop.jar $compiler
Arguments:
$1 Filename of the source file
$2 Encoding of the source file
$3 Compilation flags set in CodeRunner
$4 Path of a temporary directory
javac "$1" -d "$4"/java-compiled -encoding ${enc[$2]} $3 -cp stopndrop.jar
But now there is the Batik and College Folder with a bunch of Classes that are supposed to be loaded when they r needed.
My Question is: How do I do that?

Suppose that you have the following folder structure:
lib/
a.jar
b.jar
classes/
com/
foo/
Bar.class
Baz.class
And you need to link with all of these things to compile some code. Then you would specify as your classpath:
-cp lib/a.jar:lib/b.jar:classes

Related

Javac classpath / cp option not able to find the source file

I have a source file Example.java in the following location:
C:\Users\sushr\Desktop\Experimental Java code\tutorial
Result of dir command from tutorial directory:
Directory of C:\Users\sushr\Desktop\Experimental Java code\tutorial
10/10/2020 01:51 PM <DIR> .
10/10/2020 01:51 PM <DIR> ..
10/10/2020 01:51 PM 133 Example.java <- This is the source file
I am trying to compile this file from location C:\ .
The command that I am running from the command prompt is the following:
C:\>javac -cp "C:\Users\sushr\Desktop\Experimental Java code\tutorial" Example.java
I am getting the following error:
error: file not found: Example.java
Usage: javac <options> <source files>
use --help for a list of possible options
The classpath setting for javac is for finding other libraries and classes while compiling your .java files. It is not used for finding the .java files you specified as argument for the javac program. When you call javac Example.java and you are currently in the directory C:\, then it will look for a file C:\Example.java. It is most likely that the Example.java file will not be directly in the file system root C:\.
Either specify the .java files with an absolute path or adjust your working directory with cd "C:\Users\sushr\Desktop\Experimental Java code\tutorial\" to go in that directory and compile the files from that location.
If you specify the absolute path to your .java file you should be able to just compile it without the -cp flag like so:
C:>javac "C:\Users\sushr\Desktop\Experimental Java code\tutorial\Example.java"
In macOS, I have noticed that using the "~/" to shortcut to home, it does not work. For example:
javac -cp .:~/algs4/algs4.jar MyFile.java
Instead, I had to use the full path to locate the .jar file in order to compile:
javac -cp .:/Users/username/algs4/algs4.jar MyFile.java

How to translate an entire folder or package from Java to Objective-C?

I've used an older version of Google's Java to Objective-C (J2ObjC) converter previously (i.e. version 0.5.2) and it was straightforward to translate an entire folder of Java files to their equivalent Objective-C files (and to preserve the directory structure in doing so). I just had to run the following shell executable:
$ ./run.sh —-preservedirs <path to input folder>
I've just downloaded the latest version of J2ObjC (i.e. version 0.9.1) and it's not clear from the Getting Started page or elsewhere how I can translate an entire folder of Java files rather than just a single Java file using the j2obc executable. The only example provided in the Getting Started page is to translate a single Java file which has no dependencies or imports elsewhere as follows:
$ ./j2objc Hello.java
Can anyone provide me with an example of how to translate an entire package assuming I have a folder named input which contains my com package which contains all of the sub-packages and Java files that I want to translate?
To build a whole project, I add the source root(s) to the -sourcepath, then use the find command to locate all Java sources. For example, to build Square.com's Dagger library:
$ export J2OBJC=~/j2objc # change to wherever your distribution is
$ cd ~/src/dagger/core
$ $J2OBJC/j2objc -d build_output -sourcepath src/main/java \
-classpath $J2OBJC/lib/javax-inject.jar \
`find src/main/java -name '*.java'`
All the generated .h and .m files are now in the build_output directory, in subdirectories according to their package (like javac does). To compile all the .m files into a static library, I use:
$ cd build_output
$ j2objcc -c -I. `find . -name '*.m'`
$ libtool -static -o libdagger.a *.o
If there is no better way built into run.sh, you could use find's -exec flag:
find <path to input folder> -type f -exec --preservedirs ./run.sh {} \;
Or, you could use xargs to do multiple files at the same type:
find <path to input folder> -type f | xargs ./run.sh --preservedirs
(You might also need to add -name "*.java" to the find arguments if there are non-Java files in your directories).

How do I link jar packages together with *.java files during compilation using GCJ?

I have the following files:
A.jar (containing *.class files)
B.jar (containing *.class files)
Program.java (containing Program class with main function, which depends on A.jar and B.jar)
How can I build an executable file Program using GCJ?
It's been a while since I played around with Java so the following are mostly off the top of my head.
In linux usually a java program is launched by a wrapper script. For your case this wrapper script can be the Program, the content:
#!/bin/sh
java -cp A.jar:B.jar:/path/to/dir/where/Program.class/is/in Program
If you prefer to have only a single jar file then you can "unjar" A.jar and B.jar and create a new jar, say Program.jar that contain all the classes from A.jar, B.jar and your Program.class, and you create a little manifest file that tells which class is to be run when you execute the jar file (in this case it's your Program.class).
The content of the manifest file (let's call it manifest.txt):
-----8<------
Main-Class: Program
----->8------
Note the blank line after the "Main-Class: Program" line - it's needed.
So the create the single Program.jar:
gcj --classpath A.jar:B.jar Program.java
mkdir tmp
cd tmp
jar xf ../A.jar
jar xf ../B.jar
cp ../Program.class .
jar cmf ../manifest.txt ../Program.jar .
cd ..
Now create the shell script wrapper Program:
#!/bin/sh
java -jar /path/to/Program.jar
Make it executable:
chmod +x Program
and run it:
./Program
Applause if it works, throw rotten tomatoes otherwise!
This works for me:
gcj -c A.jar -o A.o
gcj -c B.jar -o B.o
gcj --main=Program --classpath=A.jar:B.jar -o Program A.o B.o Program.java

compile files from different directories with javac, referring a depending jar file?

I have the following set up:
I have 4 packages:
root/src/terminal - has some java files
root/src/mail - has some java files
root/src/data - has some java files
root/src/main - has a single java file, Main.java
I also have the following files
root/bin - a folder to store .class files
root/mail.jar - a jar file which has important classes used in my code
Within the root, I would like to enter a terminal command which compiles root/src/main/Main.java and puts the class files in the root/bin location.
Can someone show me the command to do this? I'm on a Mac (running Leopard).
Here's the one liner:
cd /xyz/root
rm -rf bin/*
javac -d bin -classpath mail.jar -sourcepath src main/Main.java
Alternatively, you could use absolute directory names:
rm -rf /xyz/root/bin/*
javac -d /xyz/root/bin -classpath /xyz/root/mail.jar \
-sourcepath /xyz/root/src /xyz/root/ main/Main.java
In reference to Ant you said "I would rather keep it simple.".
In fact in the long term it is simpler to create a simple Ant build.xml file. The alternative is a bunch of non-portable scripts or batch file ... or lots of typing.
To run the application, assuming that you are still in the /xyz/root directory:
java -classpath bin:mail.jar main.Main
Or on Windows:
java -classpath bin;mail.jar main.Main
Or modify the above to use absolute pathnames in the classpath argument; e.g.
java -classpath /xyz/root/bin:/xyz/root/mail.jar main.Main
Without knowing your operating system?
What you should look into is using Apache Ant. It is a build tool that once installed and configured can utilize a build.xml file in your root to compile class files to a folder as well as package a jar file.
http://ant.apache.org/
try this:
javac -cp "/root/mail.jar;/root/src;" -d "/root/bin" Main.java
This is written hoping that you have package declarations in your classes from src folder like package terminal; and package main;.
See this: Options in javac command
Or use Apache Ant as suggested by maple_shaft.
From comment give by #maple_shaft:
In Unix, Linux operating systems the classpath separator is a colon instead of a semicolon.

Comparing two .jar files

How do I compare two .jar files?
Both of them have compiled .class files.
I want the difference in terms of method changes, etc.
JAPICC, sample usage:
japi-compliance-checker OLD.jar NEW.jar
Sample reports for log4j: http://abi-laboratory.pro/java/tracker/timeline/log4j/
PkgDiff, sample usage:
pkgdiff OLD.jar NEW.jar
See sample report for args4j.
Clirr, sample usage:
java -jar clirr-core-0.6-uber.jar -o OLD.jar -n NEW.jar
If you select two files in IntellijIdea and press Ctrl + Dthen it will show you the diff. I use Ultimate and don't know if it will work with Community edition.
Rename .jar to .zip
Extract
Decompile class files with jad
Recursive diff
Extract each jar to it's own directory using the jar command with parameters xvf. i.e. jar xvf myjar.jar for each jar.
Then, use the UNIX command diff to compare the two directories. This will show the differences in the directories. You can use diff -r dir1 dir2 two recurse and show the differences in text files in each directory(.xml, .properties, etc).
This will also show if binary class files differ. To actually compare the class files you will have to decompile them as noted by others.
Create a folder and create another 2 folders inside it like old and new. add relevant jar files to the folders. then open the first folder using IntelliJ. after that click whatever 2 files do you want to compare and right-click and click compare archives.
I use to ZipDiff lib (have both Java and ant API).
Here is my script to do the process described by sje397:
#!/bin/sh
# Needed if running on Windows
FIND="/usr/bin/find"
DIFF="diff -r"
# Extract the jar (war or ear)
JAR_FILE1=$1
JAR_FILE2=$2
JAR_DIR=${PWD} # to assign to a variable
TEMP_DIR=$(mktemp -d)
echo "Extracting jars in $TEMP_DIR"
EXT_DIR1="${TEMP_DIR}/${JAR_FILE1%.*}"
EXT_DIR2="${TEMP_DIR}/${JAR_FILE2%.*}"
mkdir ${EXT_DIR1}
cd ${EXT_DIR1}
jar xf ${JAR_DIR}/${JAR_FILE1}
jad -d . -o -t2 -safe -space -b -ff -s java -r **/*.class
cd ..
mkdir ${EXT_DIR2}
cd ${EXT_DIR2}
jar xf ${JAR_DIR}/${JAR_FILE2}
jad -d . -o -t2 -safe -space -b -ff -s java -r **/*.class
cd ..
# remove class files so the diff is clean
${FIND} ${TEMP_DIR} -name '*.class' | xargs rm
# diff recursively
${DIFF} ${EXT_DIR1} ${EXT_DIR2}
I can run it on Windows using GIT for Windows. Just open a command prompt. Run bash and then execute the script from there.
Use Java Decompiler to turn the jar file into source code file, and then use WinMerge to perform comparison.
You should consult the copyright holder of the source code, to see whether it is OK to do so.
In Linux/CygWin a handy script I use at times is:
#Extract the jar (war or ear)
cd dir1
jar xvf jar-file1
for i in `ls *.class`
do
javap $i > ${i}.txt #list the functions/variables etc
done
cd dir2
jar xvf jar-file2
for i in `ls *.class`
do
javap $i > ${i}.txt #list the functions/variables etc
done
diff -r dir1 dir2 #diff recursively
If you are using IntelliJ IDEA or Android Studio, add your jar files to a project under the libs folder.
Then select the both jar files, right click then select "Compare Archives"
use java decompiler and decompile all the .class files and save all files as project structure .
then use meld diff viewer and compare as folders ..
Here's an aparently free tool http://www.extradata.com/products/jarc/
Please try http://www.osjava.org/jardiff/ - tool is old and the dependency list is large. From the docs, it looks like worth trying.
This application may be what you need, works great and display a simple GUI showing differences. Try Jarcomp

Categories