How to add your own .class into a compiled .jar file? - java

I have a .jar and I would like to add my own .class to it and recompile. Is there anywhere I can do it?

Yes, and it's simple (if you already have the .class file - then there is no recompilation).
(Assuming you have the .class file already and just want to add it to a .jar. If you don't have the .class file, you need to write a .java source file and compile it to .class first using javac)
Jar files are actually zip files - you can use zip/unzip to create and unpack them.
unzip the jar file using a unzip program
add your class to the unzipped directory (*)
zip again (possibly to another name.jar)
(*) In step 2, you must put your .class file in the correct directory - correct meaning that the package name of your class must match the directory path where you .class file resides, relative to the .jar archive root.
For example if your My.class defines that it is in package com.nicky, then it must be found at com/nicky/My.class (where com is a directory in the archive root directory). If My.class has no package, they it must be in archive root directory.
No recompilation is needed - Java does linking dynamically at runtime - if the rest of the program needs to use class com.nicky.My, it will do so successfully if the class file is in the correct place in the .jar file.
You use the classpath parameter of the virtual machine (java -cp a.jar:b.jar:... ) to tell the java process where to look for classes - in case it would make more sense to package your class(es) in a separate .jar file..
--
Edit 1 / responding to your comment:
In case you a writing a new .java file, you need to first compile it into a .class using the javac command line compiler that comes with the jdk.
Every Java class belongs to a package, which is usually declared in the first line of the .java source file. Package names must match directory path location of the class (like in the example above), for both .java source files (for compilation to succeed), and for .class files (for dynamic loading / running to succeed).
You could also download and use a Java IDE (eg. http://www.eclipse.org/downloads/packages/eclipse-ide-java-developers/mars2 )to create your .class file. Create a new Java Project in Eclipse, write your class source code, click build (if it already doesn't build automatically) and then use a file explorer to take your .class file from the 'target' directory of the project on the disk.
If your new .java class depends on classes from the .jar you are trying to add it to, use
javac -cp your.jar com/nicky/My.java
to tell the compiler where the additional compile-time dependencies are.
If you are compiling from Eclipse, you need to configure that your project depends on your.jar: Right Click on your Project -> Properties -> Java Build Path -> Libraries -> Add Jars..

Related

Eclipse - Using a .class file in Java

As part of a project I was given three files, a partially written .java file where my work will go and two separate .class files. I created a new Java Project and added the .java file and started adding/editing the starter code.
How/where should I put the .class files?
I tried adding the class files to the bin folder and dragging/dropping them into the package in Eclipse.
You should go to the project's Java Build Path property page and add a Class Folder for those two files. The contents of bin will be erased and overwritten without notice.

IntelliJ IDEA: how to make the java bytecode files (.class) compiled from the source files (.java) be in the same directory as the source files?

I am working on a project that requires the java bytecode files (.class) to be in the same directory as the source java files (.java).
Is there a certain option I can choose to make it so that I can specify that a directory is both a source file and an output file on IntelliJ?
In other words, how do I make .class and .java files both be in the top-level directory?
I am currently working on IntelliJ IDEA Ultimate 2016.1.2.
If you just want to access the .class file, you can read it as resource using ClassLoader like:
Thread.currentThread()
.getContextClassLoader().getResource("my/package/MyClass.class");

why xml files in eclipse project's source directory is copied to target/classes directory?

I have xml files in eclipse project's source directory, like:
src/java/main/com/xx/zz.xml
1.When using eclise to build automatically, xml files are copied to target/classes.
2.When using 'mvn complie', xml files are not copied to target/classes.
For the second case, I found this:why xml files in eclipse project's source directory is not copied to target/classes directory?.
but for the first case, I cannot find any document.
Can someone explain it for me ?
Thanks!
Eclipse works quite a bit differently than standalone Maven. Maven uses javac from JDK. By default javac only processes .java files and generates .class files in the same directory as .java sources. Maven asks it to generate classes in a separate directory and javac only moves .class files there.
The reason for this is that javac gives you more freedom in organizing your source files than most developers use. For instance javac does not care if your class is located in a folder structure that mimics declared packages. You can put a module together by putting several .java files along with some other files like .properties or .xml in the same folder. Your .java files can have different package declarations. For instance you can have files A.java:
package aaa.bbb;
class A {}
and B.java:
package zzz.uuu;
class B {}
If you ask javac to put classes in a target directory, it will create necessary subfolders for .class files, that will resemble the package structure. However it cannot do so for properties and xml files, because they do not contain package declarations. Such 'resource' management is left for the build tool.
Maven expects that you put such resources in another source folder (resources). They will be copied to generated package structure, so you should match it in resource folder. This is why it does not copy non-java files in source folders.
Eclipse expects you to put even .java files in a target package structure and complains if your package declaration does not reflect relative path of the file. This is where you have less freedom compared to bare javac. Thanks to this rule it can copy resources along with .class files and does not need another 'resource' folder.
You can configure Eclipse to use source folder as output folder. Eclipse will not touch resources in this case.
If you right click on the project in eclipse and select 'properties', then Java Build Path you see an input at the bottom for the Default Build Path, which should be target/classes. The source folders are shown in the main dialogue. If you click on the source folders then you can modify each, to exclude the xml files (if that is what you want to do).
Maven will include your xml files automatically if you put them in src/main/resources.
If you don't want to have xml files in build directory, you need to configure eclipse excluded source file types -
right-click on the file in the Project Explorer, choose Resource Configurations > Exclude from Build and choose the configurations that you want.

can't import jar file

I had created a jar file with three classes using this cmd line:
C:\...\db>jar cvf views.jar Line.java Points.java Shapes.java
I can add the jar file to IDE but I can't import it to the code.
Another thing is the classes in the jar file are xxx.java, but when looking in another jar file i noticed that the classes are xxx.class
I don't know if that is the problem or not.
Jar is nothing but archiving (zipping)
You are clearly zipping the .java files to your jar file.
First Compile your .java files using javac
than issue your jar command on the generated .class files
Refer How to Create Jar
You should refer to .class files when creating the JAR file instead of the source .java file.
Here you can find a tutorial about JAR creating from Oracle official site.
jar is an archive tool which is just packing your compiled java files. This means that you should compile those .java files first, and than add generated .class files in jar.
I would normally expect a .jar file to contain classes rather than .java files (or at least the source could be alongside the classes)
You can zip anything into a .jar file (it's a .zip by another name - see here for more info) but I suspect the IDE is expecting .class files. Note that my IDE (Intellij) allows me to specify a jar/zip containing source, but that's usually alongside a jar containing the compiled code.
You package java source files instead of compiled class files in the jar. If you want you jar to be used in IDE you should package class files. Something like
C:\...\db>javac Line.java Points.java Shapes.java
and then
C:\...\db>jar cvf views.jar Line.class Points.class Shapes.class

Updating .class file in jar

I want to update a .class file in a jar with a new one. What is the easiest way to do it, especially in the Eclipse IDE?
This tutorial details how to update a jar file
jar -uf jar-file <optional_folder_structure>/input-file(s)
where 'u' means update.
Do you want to do it automatically or manually? If manually, a JAR file is really just a ZIP file, so you should be able to open it with any ZIP reader. (You may need to change the extension first.) If you want to update the JAR file automatically via Eclipse, you may want to look into Ant support in Eclipse and look at the zip task.
Use jar -xvf to extract the files to a directory.
Make your changes and replace the classes.
Use jar -cvf to create a new jar file.
Simply drag and drop your new class file to the JAR using 7-Zip or Winzip. You can even modify a JAR file that is included in a WAR file using the parent folder icon, and click Ok when 7zip detects that the inside file has been modified
Jar is an archive, you can replace a file in it by yourself in your favourite file manager (Total Commander for example).
A JAR file is just a .zip in disguise. The zipped folder contains .class files.
If you're on macOS:
Rename the file to possess the '.zip' extension. e.g. myJar.jar -> myJar.zip.
Decompress the '.zip' (double click on it). A new folder called 'myJar' will appear
Find and replace the .class file with your new .class file.
Select all the contents of the folder 'myJar' and choose 'Compress x items'. DO NOT ZIP THE FOLDER ITSELF, ONLY ITS CONTENTS
Miscellaneous - Compiling a single .class file, with reference to a original jar, on macOS
Make a file myClass.java, containing your code.
Open terminal from Spotlight.
javac -classpath originalJar.jar myClass.java This will create your compiled class called myClass.class.
From here, follow the steps above. You can also use Eclipse to compile it, simply reference the original jar by right clicking on the project, 'Build Path' -> 'Add External Archives'. From here you should be able to compile it as a jar, and use the zip technique above to retrieve the class from the jar.
Editing properties/my_app.properties file inside jar:
"zip -u /var/opt/my-jar-with-dependencies.jar properties/my_app.properties". Basically "zip -u <source> <dest>", where dest is relative to the jar extract folder.
High-level steps:
Setup the environment
Use JD-GUI to peek into the JAR file
Unpack the JAR file
Modify the .class file with a Java Bytecode Editor
Update the modified classes into existing JAR file
Verify it with JD-GUI
Refer below link for detailed steps and methods to do it,
https://www.talksinfo.com/how-to-edit-class-file-from-a-jar/
1) you can extract the file into a folder called
jarname.jar
and then replace the file in the folder, handy if you are updating the class a lot while debugging
2) you can extract the jar replace the file then the jar it up again
3) Open the jar with 7 zip and drag and drop your new class in to copy over the old one
You can find source code of any .jar file online, import the same project in your IDE with basic setups. Make necessary changes in .java file and compile it for .class files.
Once compilation is done You need to extract the jar file, replace the old .class file with new one.
And use below command for reconstruct .jar file
Jar cf test.jar *
Note : I have done so many time this changes in our project, hope you will find it useful.
An alternative is not to replace the .class file in the jar file. Instead put it into a new jar file and ensure that it appears earlier on your classpath than the original jar file.
Not sure I would recommend this for production software but for development it is quick and easy.

Categories