How do I create a jar with Ant that includes the source attachment?
Maven does this, but I'm living maven-free since '03 (well, 2009, but it doesn't rhyme).
I can't see any options in the javac task which does this.
I tried including the source .java files in the fileset passed to the javac task, but this didn't work. When I try to view the source through something like Eclipse, I still get the 'no source attachment' display.
Any suggestions?
You need two things to make it work in Eclipse:
Include the source files in the file set, so that each .java file exists in the same folder in the JAR as the corresponding .class file;
In the <javac> task, add the following parameter: debug="on". That way, you encode information into the .class files about the corresponding .java files that tools like Eclipse need in order to connect the two together.
Related
There doesn't seem to be any code there. I expected to see class declarations so I could see what the code does but instead there's some
Are they somehow precompiled? What's the difference between included Jar file and a pure code?
You are looking at .class file, which is a generated when you compile .java file. To see what the program does, you have to look into .java file. You can refer official java documentation for that.
A .jar file is packaged file with .jar extension, it contains compiled java files and their class files. This file is usually imported into projects to use the classes defined in that package.
You can use "jar xf jar-file" command in command-prompt/terminal to extract the files from jar and look into the package.
A JAR will normally contain compiled class files. It may also contain source files or there may be a separate JAR that contains the source files, but not necessarily so.
If you want to use the library in your project, then a JAR of compiled class files is what you want. If you want the source code, then you'll have to see if it is available from wherever you downloaded this from. If all you want is to see how to use the classes, then probably what you want are JavaDocs for the library you are using. This is an HTML based API documentation.
Well, this is because you haven't attached any source for the mentioned dnsns.jar. You can attach source to existing JAR files in Eclipse. Refer this SO post: Is there an easy way to attach source in Eclipse?
For this specific dnsns.jar, it is part of your JRE, and if you are not able to see its source in your IDE, then it means that the Java that you have setup in IDE lacks the source. If your installation does not have the source (src.zip), then you can get it manually as mentioned on this SO post: Where to find Java JDK Source Code?
EDIT: Alternatively, you can also use a decompiler (e.g. http://jd.benow.ca/) to reverse engineer the source from byte code, though, it may not be the exact match to the original source but you can understand the overall idea. You can add the decompiler as the default program for opening .class files in eclipse Windows > Preferences > General > Editors > File Associations. Select *.class filter and add your decompiler as the program. Though, it is not as clean as attaching the source to JAR, but may work if you don't have access to source.
EDIT2: About your question
What's the difference between included Jar file and a pure code
Eclipse can find .java files for your own code because obviously they are in your workspace. But when you add a JAR file as library, it may have the source (.java) in it or not. If the source is available, eclipse can display it by default. If not, you have to add it manually.
What is the point of the javac -sourcepath option?
Say you have a file Ball.java, and file Eight.java, there seems to be no difference between running:
javac Eight.java lib/pool/Ball.java
and
javac Eight.java -sourcepath lib
The classpath makes sense to me as it means you just need to distribute class files to developers who won't need to mess with the source, but I would think you're only likely to have/need the source if it's your own/an internal project so can't understand why it's needed.
Do people have large repositories of source code instead of classes?
From further testing I've confirmed that -sourcepath doesn't even take the last modified date of the source into account like the classpath, so couldn't even conceivably save time during building. As when using -classpath, this will build the .class file if it doesn't exist and the source does, or if the .java file is newer than the .class file, whereas any source files on the sourcepath will be built again irregardless of how new they are. And when -sourcepath and -classpath are both specified then it takes the action of the classpath to only rebuild if the source files are newer, so specifying the sourcepath and classpath appears to be completely pointless.
I've also tested to make sure that -sourcepath and -classpath both only build the necessary source files needed for resolution.
The only upside from -sourcepath over specifying the specific .java files I can find is that sourcepath just has to have a directory specified, and any jar or zip files are automatically extracted.
So is the point of -sourcepath due to laziness (not wanting to extract & specify all the source files)?
And is there any upside to using -sourcepath over -classpath? Since they appear to do the same thing but classpath performs it better by saving time when the source doesn't need rebuilding.
The sourcepath is used to locate .java files for classes referenced in the files you asked to compile (Eight.java in your example) for which no .class file exists. The compiler will automatically compile those too. I'm not sure if it compares the modified-time of the .java and corresponding .class file and recompiles the .java if it is newer, but I think it does.
I've found from further colleagues in development that they would generally use this during development if they want to build part of a project or subproject. Instead of building everything from scratch (which could take hours), they instead simply want to build a few projects, then they can specify other directories of the whole project in -sourcepath so that this can resolve classes. This means it can automatically find what dependencies it needs and build these as and when they are needed.
I've also been informed that this can be helpful during maven builds since the order of dependency gathering can be very unorganised. Instead of having missing dependencies because the jars aren't there at time of building, you can specify the entire code tree as the sourcepath. Although I imagine this isn't the best advice, it's helpful when somebody is having problems building.
I have made a small program in Java that displays its .java source with a gui. It does not use FileChooser to do this. I am reading the .java sources with the aid of following statements
String resName = "/dev/classes/"+name+".java"
Scanner s = new Scanner(FilePrinter.class.getResourceAsStream(resName));
where name is the name of the .java file i.e. if the file is MyProg.java then name==Myprog. Of course my program is inside the dev.classes package
The thing is that when I export my project to JAR and include source files this works because source files reside inside the /dev/classes/ directory.
However, I haven't yet discovered a way to make my program run in Eclipse or from the command line without giving me exception.
And of course when someone tries to add those source files to be used automatically as resource files the process fails.
Can I somehow use the same code both when running from Eclipse and from the JAR? It must be something very trivial but because I am not Java expert I cannot see.
I found how to do it. Actually you either have to use Ant or Maven. However, this can be done in Eclipse as well as follows:
On the Eclipse Project Properties>Java Build Path you can choose on the bottom Default Output folder: <your_project_name>/src.
This causes class files be compiled in the same directory as the .java files and finally does what I wanted.
Thanks to #AndrewThompson for suggesting to try this
Back story:
Long ago, before dinosaurs were around, there was a contractor that wrote a small Java program, that does some stuff, and prints some stuff to the screen.
Current: No one here knows much about Java but me - and I am not fluent.
The program works, but we kind of need just a bit more information on the screen. From the documentation available, I think I know how to go about that, and I definitely know how to print stuff, as it's simply using System.out.println() for this.
I have a .jar file, which I'm 99% certain is being loaded/used, which contains .java files matching every .class file within.
Is there an easy way to (and how might I) slightly modify one of the .java files, and "compile" the new version to replace the current matching .class file within the .jar?
I'm able to open and read the java source file, of course, but don't remember to procedures to turn java into "class" files, and especially not sure if I can just drop the resulting .class file into the .jar file as a replacement.
at the basic level, javac is the compiler; that will produce the .class files. There is also a "jar" command that will regenerate your jar file. Depending on the number of dependencies, that can get complicated quick. You can just type "javac" and "jar" (w/o quotes) to get the args to run it. Another option is to setup an ant build script...
so you could do something like (assuming windows OS):
javac -cp %MY_CLS_PTH% *.java
where MY_CLS_PTH is where any dependent classes are. If you have a package structure, this gets a little more complicated.
jar -cvf .\my_class_dir MyJarFile.jar
where my_class_dir is the directory that contains the .class files.
I think that is right (didn't run it myself) but that should be about the basics...
EDIT: There is a way to just add/re-add a single .class file to an existing jar file. Check out the "jar" command's usage, looks like "-u" will update it (of course you have to pass in the .class file). Also remember that any package structure you have in these classes, you need that directory structure and you reference the class via that dir structure. (Hope that is clear...)
Add myclass.class to the top level directory in myjar.jar:
jar uf myjar.jar myclass.class
Add myclass.class to the subdir directory in myjar.jar:
jar uf myjar.jar -C subdir myclass.class
Add a Version attribute to the manifest of myjar.jar:
First create a file somefile containing the line Version: "X.Y.Z", then
jar umf somefile myjar.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.