问题
But when I add the external jar file to a project it doesn't put the java files in the src. What do I do?
回答1:
Jar files are usually a compiled form of your java classes. The source CAN be included with the jar, but it rarely is. So instead of the expected ".java" files, you'll see ".class" files, which are compiled forms of your code. If you want to edit the files, you have a couple of options
Look for the source elsewhere
This is your best bet really. If its an open source project, look for the source of it. You can probably google it pretty easily, or search in search engines for maven repositories like this one. For example, if you see here, I looked for junit, and found an entry called "sources.jar".
If its not an open source project, but a project internal to your work, there might be a team in charge of that project. Reach out to them, as getting the original sources as they where originally compiled is really your best choice.
But what if you absolutely do not have access to the source code. Well then, you have two options. I would only recommend these options if you are VERY familiar with Java, as they can cause a lot more trouble than they can solve.
Extending classes and replacing methods
I'm assuming the reason for you wanting to do this is to edit a small part of the behavior of one of the classes, and then use that changed class in a project of yours that you DO have access to the code in; and that the class that you want to extend isn't final. In this case you can extend the class, creating a subclass and then override the method that controls that small functionality you want to change.
Now, this can be a pretty dangerous idea if you aren't careful with what you are doing. The reason being is that if you don't have access to the code, then you cannot know for sure how the implementation details work. Which might lead to errors. The lack of visibility to the original code can lead to
- Overriding a method in such a way that the original functionality of the class is broken. This may happen because a method that you overwrote might have been doing certain internal actions that might not be obvious to you.
- There might be fields and methods on the original class that are non public or non protected which your new class may not have access to. So you may not be able to fully replace the functionality with the functionality desired.
So, what if all those reasons why this might not be the best idea do worry you? There is one more way to replace functionality directly on the class.
Decompiling the project
There are many Java decompilers available that will take a ".class" file, and convert it to a ".java" file, some that even integrate with eclipse. However, this has severe disadvantages over acquiring the original source
- It might not be legal. If the jar you have is provided by a license it is VERY likely that you'd be breaking the license agreement you agreed to before downloading and using said jar.
- The code will not be easy to read. You'll loose most of the nice naming conventions originally included in the source code, making the code very hard to read.
Decompiling and recompilinig can very easily lead to more bugs than its worth. Its entirely possible to use well, but I'd advice you to stay away if possible.
So, what should you do?
Composition, no reimplementing
I'm guessing right now you have a jar, that provides a class (or list of classes) that does almost pretty much what you want, but not exactly. Well, how about instead of changing the original source (which you don't seem to have access to) you use that class, and create a method to change it's final components to what you want it to be. You could do this by creating a class that contains your desired class as a field, and have it modify it. For example, lets say your jar a class called EuropeanCar, and you like it, but want to have an AmericanCar instead, and the only difference is that the American car returns its current speed in "Miles per hour" instead of the EuropeanCar's "Kilometers per hour". But all other functionality is 100 percent the same in this example.
You could have something like this:
public class AmericanCar
{
//...
private EuropeanCar internalEuropeanCar;
//...
public double getCurrentSpeed()
{
return AmericanCar.convertKilometerToMiles(this.internalEuropeanCar.getCurrentSpeed());
}
private static double convertKilometerToMiles(double currentSpeed)
{
// ...
return CONVESION_VALUES;
}
//...
}
That is an overly simplified example ofcourse, but the idea is to use components, and these components can be of the type provided in the jar for you to use in your program. This is by far the cleanest solution to your problem IF you don't have access to the original source code, and even if you do, it might be a better choice depending on the change you want to make.
来源:https://stackoverflow.com/questions/17055568/i-have-an-external-executable-jar-file-that-i-wish-to-edit-the-java-files-in-it