I want to add some class files to rt.jar. How am I able to do that?
Your question indicates you have some misunderstanding of the java platform.
First of all you need to know what the rt.jar is and what it does:
rt.jar is the jar that contains all the classes necessary for the java runtime. Hence it's name rt.jar
Now that you know that, you need to know how your java program runs:
Your java program, all your jars and classes are executed by the java virtual machine.
So as you can see the code you write & the rt.jar which is used by the java run time are completely separate and should remain so.
If you need some functionality you should add it to your jar.
Do not update it. Why do you want to update it?
Well anyhow if you want to update it, I know one way, You can open jar file in winrar and paste updated .class files in archive. But your jar may get in inconsistent state. Do it at your own risk.
You can use this command:
jar uf jar-file input-file(s)
Refer the link for details:
java.sun.com/docs/books/tutorial/deployment/jar/update.html
The best way to update the rt.jar is to install a newer version for Java. ;)
If you want to add your own classes in new packages, you can add these to a jar which is in your class path. This is preferable to changing existing classes.
If the only option is to change existing classes, you can create a "patch" in a jar which you prepend to your boot class path, or you can add the jar to an lib/endorsed directory. I wouldn't do this for production code, only for your own testing.
I've tried jar.exe with the u and 0 (i.e. zero) options and that gets the closest to looking like the original rt.jar file but if I've updated the JDK's JRE's rt.jar I have problems with compiling and jarring after the update. No idea why! Simply running a program with the JRE seems to work.
I also tried -Xbootclasspath/p but couldn't get it to work.
Looking at Replace a class within the Java class library with a custom version I see that there are legal problems with distributing an altered rt.jar to your customers, even if you could figure out how to do it correctly. So I plan to take the advice in that page and create a java agent. That's apparently legal and works.
One reason a person might want to modify rt.jar is to add debugging information after compiling the source that comes with the JDK with the -g option. One may also want to patch something. These would be for one's own use, of course.
Related
I have an older Jar file which I have to modify in order to get it to work.
I have already decompiled it with jd-gui and changed the parts that needed change. I would now like to know what I have to do in order to get a jar back?
I guess that I have to add the libraries, but there is no extra lib directory.
How do I put everything together?
#Stephen C
"Therefore, when you make your changes and recompile, the resulting ".class" file could have unexpected "
How exactly is this relevant? I only want the function of the Jar file and not a 1:1 copy of it.
The Jar file is unsigned. What exactly would be the reason to sign a Jar file anyway? If I start it from another program?
If you are missing dependencies after decompiling the entire jar, that could mean the jar did not include them. When you create a jar, you can choose not to include dependencies in it, but this assumes that they will be available on the classpath at runtime. Check if there are any relationships with other jar files on the classpath when you run the original jar. See this answer for details on how to achieve this. Once you have identified all the dependencies, you can easily compile the jar from an IDE such as IntelliJ/Eclipse or from command line.
As a side note, if the changes you would like to make to the jar are minor or isolated I recommend editing the bytecode (much easier for small edits). I prefer this bytecode editor.
If decompilation fails on some parts of the code, the functionality of the jar will not be restored upon recompilation. In this case, instead of going through all available decompilers and hoping that you can decompile that code, I suggest you identify the set of classes which you are trying to edit, modify the rest of the classes such that they compile and do not have any side effects on the classes which are of interest to you (do not delete anything that is referenced by these) and compile the jar (even if this isn't the jar you want). You can then extract only the class files which you wanted to modify from the jar, and overwrite them in the original jar. This will only work if your changes didn't have any side effects.
If you are asking how to create a JAR:
You can do it using a build tool such as Maven, Gradle, Ant and so on.
You can do it using a Java IDE
You can do it using the command line jar tool; see How to create a JAR file from the official Oracle Java tutorials.
But it there is no guarantee that what you are doing will actually work. Here are a couple of the problems.
If the original JAR file was signed, you won't be able to re-sign the new JAR ... unless you have the private key that was used when signing.
Decompilation is often inaccurate. There is no guarantee that the Java code that it produces is a correct representation of the original class. Therefore, when you make your changes and recompile, the resulting ".class" file could have unexpected / unwanted differences relative to the original.
I guess that I have to add the libraries, but there is no extra lib directory.
I'm not sure what you mean by that. The (new) dependencies of the JAR don't necessarily need to be in the JAR itself. It depends on what kind of JAR it is; e.g. is it a so-called "executable" JAR that you launch using java -jar my.jar ....
Use jar plugins for gradle or maven for example, or build it with intelliJ, here's an answer in another post: How to build jars from IntelliJ properly?
Since I had trouble getting the .jar file completely recompiled and working with my application, I wanted to share here the steps that were missing in the previous answers.
In my specific case, to make things as easy as possible, I wanted to only modify one .java file in the result of the decompilation and update it directly in the .jar file.
I started from the answer from Paulo Ebermann on a similar question, and I ended up with:
javac -source 8 -target 8 -d classdir -cp \
"\
path/to/dep1.jar; \
path/to/dep2.jar; \
path/to/myoriginal.jar \
" path/to/my/java/class.java
cd classdir
jar -uf path/to/myoriginal.jar path/to/my/java/class.class
Notes:
the path/to/myoriginal.jar which is in the path of the dependencies, this forces the java compiler to look for missing classses in the original .jar file rather than in the local decompiled code (which would require recompilation and more dependencies) and therefore I have intentionally left out the . path in the list of class paths
the -source 8 -target 8 which were required to force the class to compile for the appropriate version of the runtime machine.
the -uf which indicates that the jar tool should only update the file with the provided class
I'm having trouble adding a .jar file I downloaded for my Java project. This is really the first time I've used eclipse, so please bear with me and for some reason (I have no clue why), I just find it somewhat confusing.
I know that in order reference different class files you simply need to create a class library and add it to the build path. From there, all which needs to be done (unless I'm misunderstanding this for whatever reason) is use the "import" keyword to import whatever .jar, .java, or .class/.interface file necessary into the project.
I've tried that with my .jar. I have it referenced in the build path (all I did was just copy the jar to the project directory, and then use the build path option to add it externally), but when ever try to call the object "Delegator", which obviously is a part of the .jar file, it won't read.
Am I missing something here? Seriously, anyone who knows the answer to this - you're relieving a mother of a headache. And before anyone asks - yes, I've searched this one to death. I've found similar questions, but nothing which quite hit what I was looking for. Either that, or I really just lack the common sense.
Right click on project->BuildPath->Libraries->Addexternaljar and then press ok and if it doesnot worked then you should go to the Order and Export tab and checked the jar you have just added in your project. It will solved your problem.
There are several possible reasons, for the question hasn't mentioned the specific failure, and where it has occurred. The following is a list of possible reasons I could think of, but this may not be exhaustive:
You can import a class, in a different package only if the class is public. The only exception is when you are using the class in the same package. If the class is an inner class marked as private, then you're well and truly out of luck. The Delegator class in question might not be public, and that's why you may be unable to use it. This issue ought to be caught by the compiler.
The directory structure within the JAR might not match your package import statements in your classes. This might not be necessary, for Eclipse ought to provide possible fixes, but it is better to verify that nevertheless. Again, the compiler should complain if this is the case.
If the issue is at runtime, then, it is most likely that the JAR is not available in the runtime classpath. You'll need to configure the Runtime configuration, to add the JAR to the runtime classpath. Refer to the Eclipse documentation on run configurations, if you need to know how to change the runtime classpath.
Note:
Exporting the build classpath entries would matter to other projects that depend on the pertinent project; unexported entries will have to be re-imported if required in other projects. This would not apply to a run configuration.
Update
Every Java application needs a main(String[] args] method to start execution. This is the entrypoint for the application. From the comment, it appears that the main method is in a different class. If so, the said class ought to be used to start the application. In Eclipse, a "Run configuration" might be used for the class that lacks this entrypoint, resulting in the described error. One can rectify this by creating a new Run configuration for the class with the said entrypoint. This may be done by one of the following:
editing the existing Run configuration to use the desired Class (the one with the main method). See the above link, in the third bullet point. Edit the value of the class to be launched.
creating a new Run configuration for the desired Class. Usually, you'll need to traverse to the desired class, and run your application (using the Alt+Shift+X+J shortcut) from the said class.
i was facing similar issue with spring jar files but then tried with different jar files and it work so I think , classes defined in jar files were private and not available outside of jar hence you were not able to access the file .
thanks ,
Raju Rathi
Right click on the project--->Build Path--->Configure Build Path...--->In left side you have to choose Java Build Path--->Libraries--->Add External JARs--->ok--->ok
Steps to add jar file in eclipse
1. right click on project
2. click on Bulid Path->configure path
3. click on java Build path
4. Click on libraries tab
5. click on add external jar tab
6. choose jar file
7 click on ok
Copy the .jar file in libs folder which you want to add in your project.
Right click on .jar file -> Add Build Path
Done.
Anyone who uses Java regularly knows the amount of trouble multiple jars in classpath can give us. I am looking for a tool which will help me -
Search for class files inside jars in Classpath
Search for class files inside jars in a specific location
Maybe too much to ask for but show me if the same class is present in multiple jars.
Also needless to say it should be fast. Most of the tools i have evaluated are very slow and not upto the mark.
Any tools for the above purpose greatly appreciated.
Currently i use WinRar achieve search(which BTW is really fast) to search for class files inside jars in a specific location. But there is no way to utilize that to search in Classpath.
If you use Bash this script may be helpful:
find . -name *.jar -exec bash -c "echo {} && jar tvf {} | grep MyClass" \;
If you are using eclipse, then IBM's classfinder may be useful. You can perform a (fuzzy) search for a class in a (set of) directories, and get all jar that contains such a class.
Not sure about the classpath option, however.
regards,
Guillaume
You can use jarbrowser for this
If you're using Eclipse, and they're on your classpath, you can CapitalCaseControlSpace what you want.
For example, if I want to get a new ApacheFanUtilityMethodizerFunctor (which everyone needs, of course) I simply type AFUMF and then Ctrl+Space and it populates it for me. Since it's already on my classpath, I don't need to hunt for it, because it's there.
Now, if it wasn't on my classpath, and I had to find what jar it was in for purposes of including it, then back to WinRAR (or for me, Google typically) I go.
My own solution for managing java jars files and java classpath is really simple. Firstly I create folder inside e.g.:
C:\Program Files\Java\libraries\
Here I put all my *.jar files which i need to use.
Then I modify the:
PATH(modyfy also CLASSPATH or JAVA_HOME)
system variable and add this path shown above.
Problem occurs when one class is in two diffrent jars but I managed my jar to avoid this problem.
Now when java is running jvm can find my classes and ClassNoFoundException isn't thrown.
A late response, but in case anyone searching has a similar problem, I wrote a simple tool a few years back that I use all the time for this sort of problem.
It's free to use and open source. If you find it useful, let me know, :-)
https://github.com/eurozulu/Findclass
we have downloaded jar files for lambdaj and its dependencies which are again jar files.
we do not know how to go about it. we have copied these files in the
C:\Program Files\Java\jre6\lib\ext
have set the class path in environment variales as:
variable: classpath
path: C:\Program Files\Java\jre6\lib\ext
but we do not know how to go further. we want to run some lambdaj programs.
can anyone suggest how to run lambdaj programs?
You would run a Java program that requires lambdaj in exactly the same way you'd run any other java program with an external dependency, i.e. by invoking the java executable passing in the fully-qualified name of the Main class, or the JAR with an appropriate manifest, or by deploying it in a servlet container, etc. Additionally you should be putting the LambdaJ JAR on the classpath for this invocation, not in the lib folder for your entire JVM.
What have you tried so far and why/how is it not working? Your question at the moment is a bit analogous to "I want to use Microsoft Word to view some Word documents, how do I do this?".
Update for comment 1: You said "it's not working". That doesn't help anyone address your problem as it gives no clue what you expected to happen and what you observed, only that they were different. As for where JAR files can be stored - you can put them in any directory, so long as that directory is on the classpath (or you add it to the classpath) of the Java application that runs. The canonical place to put external dependencies is in a folder called lib below the root of your project, but the important thing is that you choose somewhere consistent and sensible.
It sounds like you don't quite grok Java and classpaths yet. If you have followed some tutorials and are still stuck, ask for help to let you understand. Adding more detail to your question, including the layout of your files, the commands you issued, and the response that came back would be useful too.
If you are using Netbeans create a project and right click on the Libraries folder within the desired project. Click Add JAR/Folder...
I downloaded the Javax.mail package. I have jdk1.6.0_11.
Problem is...I cannot get javac or java to find those classes!
I can get apps to compile using JCreator LE ( by adding the mail jar
to its search list ) but, when I try to run the app in a command window,
it fails.
Can I add these new classes to the rt.jar without
hurting my jdk installation?
I know java has it wired up to look there for classes.
(And, the mail classes are inside a javax package - seems like
they could reasonably be added to the javax folder in rt.jar..
Thanks!
Phil D'
No you can't, nor should you.
Instead, figure out the problem with your classloader (probably paths?). You'll need that for the next library you need to access.
Messing with rt.jar means you can't run on any other JVM.
You should either specify the jar file in your classpath: preferably on the command line with the -cp option, but possibly with the CLASSPATH environment variable.
Alternatively, you can specify its directory in the java.ext.dirs system property. For more details, see the documentation for the extensions mechanism.
You shouldn't be messing around with rt.jar. That's very definitely not the way to make extra jar files available - it's akin to trying to add Microsoft Word to the Windows kernel ;)
Adding things to rt.jar seems like a bad idea, even though its possible and easy to accomplish.
Try compile your application from the command line like this:
javac -cp <path_to_3rd_libs>/jarfile.jar . MainClass.java
If the compiler still complains about the javax.mail package try to unpack/examine the jar file to see that javax.mail package (and its expected content) is there.
(On windows its easy to examine a jar file using 7zip.)
Most definitely no.
If you post the command you are running from the command line we will be able to point you on the right direction, but most likely you are just missing a classpath parameter.
java -classpath /path/to/mail.jar MyClass
You need to understand the CLASSPATH concept which allows you to add individual classes and jar files containing classes to the "universe" of defined classes available for the code you want to compile and/or run. It is similar in idea to the PATH variable in the Windows world.
For the Windows command line this is the documentation:
http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html
The Java Tutorial surprised me by not being well-written for this particular concept:
http://java.sun.com/docs/books/tutorial/essential/environment/paths.html
You most likely need something along the lines:
C:> set CLASSPATH=c:\javamail\first.jar;c:\javamail\second.jar
after which both java and javac should know about these classes