Re-compile a Java Class from Jar - java

I have an executable jar that has one class file with a wrong value. I requested that file from the author and corrected the value.
Now I want to compile it and add the compiled class file into the jar and run it.
Not surprisingly I get multiple "cannot find symbol" errors for references of custom object that were in the jar file.
I tried to compile the file by referencing the jar file in the classpath like so
C:/> javac file.java -classpath C:/folder/where/jar/is
but this doesnt seem to work... I get the same errors as if just doing
C:/> javac file.java
Is there a way to compile this individual class somehow referencing the other files in the jar?
Thanks.
Errors I am getting while following some of the suggestions below here:
javac -classpath C:/jar/location.jar File.java
File.java:226: cannot find symbol
symbol : class Stuff
location: class com.shared.stuffers
Stuff s1 = new Stuff();
^
Stuff class is found in the Jar, but can not be seen by the javac program... I feel like I am doing something wrong but not sure where? Thanks.

You will want to compile your file like so:
javac -classpath C:\folder\where\jar\is\the_jar_file.jar file.java
per the javac usage instructions:
C:\Console2>javac -help
Usage: javac <options> <source files>

Once you've compiled the new file (such as in Mr. Will's answer), you can add the new file to the jar using:
jar uf C:\folder\where\jar\is\the_jar_file.jar file.class

You probably have to specify the JAR file itself and not just the directory it resides in.
javac file.java -classpath C:\folder\where\jar\is\the_jar_file.jar

I'm just guessing, but did you check whether it doesn't need any external jar libraries you may have to include in your compilation command? Another thing you could do is to compile all of the classes by doing something like
javac *.java ...

As others have mentioned, once you have the .class file recompiled you need to replace the older version in the .jar
You'll likely need to have any compile time dependencies available to rebuild this class. If it's an open source project this could be an easy thing to come up with. If not, it's more difficult. If the author sent you the file he can probably help you with this as well. You might be able to get the author to produce a patched distribution for you as well. Odds are he/she already has the build environment set up and this should be relatively easy to do.

I'd try this approach (and it should work, unless the 'debugged' class doesn't introduce a new error):
create a new jar by taking the old
one and deleting the classfile that
you want to replace
compile the
corrected java file and make sure
that the modified jar is on the
classpath
add the newly compiled
classfile to the jar
This should work. If not - ask the author for a new complete library.

Related

Compiling a java file using javac and the command line

I am trying to learn more about javac and how to use developer tools for Java using the command line.
As far as I understood, the option -classpath is needed to specify the path where javac searches for our classes and resource files, if we are not in the current directory, because usually the class path is set to our current working directory.
This is my current working directory:
/Users/user1/Desktop
And I am trying to compile a .java file which is in:
/Users/user1/Desktop/PF/
and the file is called MainClass.java.
I am trying to compile it using the following command:
javac -classpath /PF MainClass.java
But it does not seem to work, in fact I keep receiving the following:
javac: file not found: MainClass.java
Usage: javac <options> <source files>
use -help for a list of possible options
What am I doing wrong?
Classpath is for .class files, not for .java files.
javac command needs correct path to the .java file to compile it. So
javac ./PF/MainClass.java
Will create the class file in current directory.
If your MainClass.java depends on any class files to compile correctly, then you put those class/jar files in classpath.
That isn't how the classpath works. You use the classpath to point to classes that your Java file needs in order to compile. You don't use the classpath to point to the Java file itself.
Either go into the PF directory and do this:
javac MainClass.java
That will create the MainClass.class file inside the PF directory. If instead you want to create the MainClass.class file on your desktop, then from your desktop, do this:
javac PF/MainClass.java
-classpath
Specifies the path javac uses to look up classes needed to run javac
or being referenced by other classes you are compiling. Overrides the
default or the CLASSPATH environment variable if it is set.
Directories are separated by colons. It is often useful for the
directory containing the source files to be on the class path. You
should always include the system classes at the end of the path.
class path is used to specify the compiled sources that need to be used in your class. For example in this code if you are accessing another class then you should specify the location of the compiled sources of the that class.
In your case if don't have any class dependency then simply remove classpath option and compile using[navigate inside folder]
javac Mainclass.java
Remove the -classpath. And if you are in the place where the java file is required (which currently you arent) you can remove that PF/ too.

How can I compile files when my current working directory is not the default package?

I have two files in Linux, both in the default package, AddSingleInstance.java and Finder.java
I am creating an instance of AddSingleInstance in Finder:
AddSingleInstance ai = new AddSingleInstance();
When I compile Finder.java file it gives the below error:
Finder.java:20: error: cannot find symbol
AddSingleInstance ai = new AddSingleInstance();
^
I'm compiling from a different directory. How can I get both files to compile successfully?
To fix your problem, your java files should be on your classpath so that javac knows where to find them. You can either manually set the classpath:
javac -classpath javadir javadir\Finder.java
java -cp javadir Finder
Or use the default classpath of .:$PATH. The easiest way to do that is
cd javadir
javac Finder.java
java Finder
I guess most people don't encounter this issue (I never have before!) because they run javac from their default package (the root of their source tree).
If they are in the same package then AddSingleInstance should be accessible in Finder and vice versa.
However if they are in separate packages, then add the following line at the top of Finder.java (after package declaration)
import packageName.AddSingleInstance;
Possible your source file is using Windows style line feeds.
Try using the program dos2unix to fix the line feeds and try recompiling. I'd also have to see the complete source file to help further, I'm assuming you have the imports at the top of the file.

How can I include packages(folders) in the compilation of a java project through terminal?

So, I want to compile a java benchmark.
I am working inside the folder /home/username/Tools/myTool/folder2.
I am compiling with javac -cp /home/username/Tools/appv1.0/ *.java
folder1 compile sucesfully because it did not have any dependencies on packages.
Right inside folder 2, that I have the problem, there are 5 folders residing as packages(having some java classes), but the compiler can not recognize them, so I need to put that explicitly.
And I keep getting errors like this
JClass1.java:22: error: package crypt does not exist
import crypt.*;
^
JClass2.java:23: error: package series does not exist
import series.*;
^
So, how can I direct the compiler towards those packages?
Thanks in advance.
You must write the command to compile as:
javac -d bin -sourcepath src -cp lib/lib1.jar;lib/lib2.jar src/com/example/YOUR_FILE_NAME.java
As a result bin/com/example/Application.class file should be created. If Application.java uses other classes from the project, they all should be automatically compiled and put into corresponding folders.
For more info.
The anwser provided by yogx was the right one after all!!
Problem solved.
javac -cp dir1/*:dir2/* MainClass.java
Thank you all!

How do I compile and run a particular .java file in a package from CMD?

While there have been many questions related to this, I couldn't find one that specifically answers this.
This is the file structure of my source code in Eclipse. Now I want to run serverStart.java in some machines, and clientStart.java in some other machines.
It has to be compiled and run from command line (CMD) from the source code. I am not allowed to use Eclipse. What command do I use to compile and run the project? Should I create a jar file for this, or use javac? (I tried using javac on clientStart and it gave me some errors (Cannot find symbol), related to other classes like clientData that are in the same package)
Note that clientStart and serverStart have "public static void main(String args[])" and also create objects of other classes like clientACK.java.
This is the folder structure in windows -
EDIT: I also have .class files for each in the bin folder. Are they useful in any way?
cd\
C:\cd IP\IP_proj2\src
C:\IP\IP_proj2\src> javac IP_proj2.clientACK.java
C:\IP\IP_proj2\src> java IP_proj2.clientACK
Third compiles, fourth runs.
Answering my own question,
I had to navigate to the parent directory, which is C:\IP\IP_proj2\src in this case. From here, I use the command.
javac IP_proj2/*.java
The key here is to compile them all at the same time using *.java I believe. When I tried it out individually, it gave "cannot find symbol" errors.
Command to run it -
java IP_proj2.serverStart

Java: class resolved?

I hope this question is not repeated. But just can't find answer anywhere:
I have ONE folder containing two files one A.java another B.class.
Now in A.java I am trying to declare
public class A extends Applet{
...
B aB;
}
The compiler gives me:
B cannot be resolved to a type
I read a lot of posts that say if the files are in the same folder, I don't need to import. Could anyone help me to "resolve" this problem?
Thanks much appreciated!
-----------SOLVED! - SEE ANSWER BELOW------------------
The .class files need to reside in a directory referenced by the classpath variable. Usually you put your .java files in one directory (src), compile to another directory (bin) and have external .class files in a third directory (lib). The commands will look like this:
# compile
javac -sourcepath src -classpath lib -d bin
# run
java -classpath bin:lib A
Using an IDE like eclipse should help a lot here as it takes care of most of the details
The simple case that you've posted works for me. I'd check the following things:
Are you sure that B.class is present in the same folder as A.java?
Are you running javac from that folder?
Have you typed the class name B correctly everywhere in your program? This includes capitalization, as Java identifiers are case sensitive.
Are there any package declarations in your program? If there are, none of this is going to work, since you're implicitly using the default package by just throwing everything into a folder.
The compiler looks for *.class file in its class path. It will only look for *.java files in the same source directories. You need to set the class path to include the directory.
Or you could use an IDE which sets all this up for you and saves a lot time in the process.

Categories

Resources