We have about 280 Java source code spread over 10 packages, and a bunch of txt and image files for a software project. Quite a few of them are not being used currently. They do not break the system, since we can just do a "javac //*.java" and "jar cmf metafile " to build up the executable jar which works. The question:
How do we find the class files never accessed, or image/txt files never used as resources in the jar?
It would be very hard to determine which image/txt files are never used, as they can be loaded in a variety of manners. A good bet for the image/txt files is to search for the name of each file in your code; if it is not there, it might not be being used; remember, the name of the file could be being generated programmatically and then loaded.
I recently had to do something similar for a game project. Because content could be brought in via a variety of means, removing unused content took a lot of trial and error.
There are plugins for eclipse that can find unused code.
Use the Unused Code detector: http://www.ucdetector.org/
It has been answered in How to find unused/dead code in java projects.
For the images, I would write a small program, pseudocode would look like:
//list image names
//for each image name
//find ocurrences in other files
Related
How can I export files to eclipse project from the target folder?
I lost my project files. All I have is a target folder with binary .class files and static files in html.
Can you somehow build a project out of it?
Not possible. You can't go back to the original source files from just class files. You could decompile them which means you get code stripped of all names and comments except for method/fieldnames, code is mangled and worse, and probably broken. If you must - Here are some decompilers. Not sure if that site truly works (sites that only load over plain jane http are rather suspicious), but even if not, just search the web for any of the decompilers named there and run it on those class files.
As I said, the end result will look horrible, but it's the best you can do.
I need to use a library for my Java code, which comes in a handful (10 of them, to be exact) of .JAR files. No problem here.
The issue is trying to access these libraries' source code/files, so that my IDE can help me not f**k up anything.
See, the library actually did come with source files. One for each .JAR file.
The .JAR files are named in the format <pathToPackage>-<version>.jar, and the source files are named in the format <pathToPackage>.source-<version>.jar, with <pathToPackage> and <version> matching for every .JAR-source file duo.
However, for some unknown reason, only two (2) of them are successfully picked up by the IDE.
I tried with VScode (with the Java Language Support extension), and IntelliJ, both giving the same result.
All of the source files are "proper" source files. I extracted their content in a separate folder, and am using that to navigate the source code.
Here are the files, for reference (grouped by which ones work, and which ones don't):
https://drive.google.com/file/d/1MISJ7vML7WI9BDzPXf7yGtrTWc7MgRjI/view
This question already has answers here:
Java images not appearing in JAR file [duplicate]
(4 answers)
Closed 2 years ago.
I couldn't find an answer that works so I had to ask here. I have splashscreen file with the contents
JLabel image=new JLabel(new ImageIcon("./image/risk.jpg"));
And the folder structure looks like this
But for some reason when I go to create a jar file like this
The images don't appear in the jar file. I have looked at many other answers and they don't seem to work. I would greatly appreciate an expert eye to tell me what I am missing. Thanks in advance
new ImageIcon("./image/risk.jpg")
The images don't appear in the jar file
Non sequitur. Whether the image file is in that jar or not is irrelevant; this does not work with jar files, period.
That ImageIcon constructor takes in a file argument. File, here, is to be taken literally: It refers to a path to a file on your actual disk. You go with ., meaning: Current working directory, and thereby have lost all chances at a stable app; current working directory is whatever the JVM got started from and therefore unreliable. Even if you wave a magic wand and solve that problem, the next more pressing issue is that there is no risk.jpg file anywhere - it's an entry in a jar file, which is not, itself, a file. Merely an entry in a jar.
The solution
The solution is not to use that constructor, and instead to rely on java's resource retrieval system:
class MyClass {
public void foo() {
URL url = MyClass.class.getResource("risk.jpg");
}
}
This gets you a URL that represents a resource (could be an actual file, but could also be an entry on disk, the web, from a database, generated on the fly - whatever the classloader is providing. If you didn't mess with custom classloaders, it will always be either a file on disk, or entry in a jar file), and this can also be passed to ImageIcon (it also has a constructor that takes a URL).
This then looks for a file named risk.jpg which is sitting in the same place that MyClass.class is sitting. Whether that is on disk someplace, or in a jar file (so if this is in package com.foo;, you have a jar file with entry com/foo/MyClass.class, and that command would then find the entry com/foo/risk.jpg in the same jar file. You can use a prefix slash to go from the root of the jar: MyClass.class.getResource("/image/risk.jpg") (note, no leading dot!) will look in that jar for entry image/risk.jpg.
Great! Uh, but, that image should be in the jar, right?
Yes, this code will ensure you look in the same place class files are, which is good, but you still need to ensure the build is set up properly. 'let eclipse make a jar' is not a recommended build solution; invest some time in learning maven or gradle. However, if you insist, eclipse should just include them, but put the jpg in a source dir, right next to your java file (eclipse knows that non-java files are to be copied over, and java files are to be compiled).
In other words, if you insist on using eclipse's 'make a jar' as build tool, image has to move into src.
Alternatively, set up a basic maven project, where source is in src/main/java and image files and the like are in src/main/resources, use the maven plugin in eclipse to read the maven based project in, and that works too, if you want these directories fully separated for some reason.
I realize this may seem like a completely stupid question and this question is a "wall of text", but I'm feeling like I've gotten way out of my depth here and need some guidance. I've read several SO questions on this topic, but still can't seem to find one that addresses this particular situation. (please reference update(s) at the end of this post)
BACKGROUND
Our company has an application that was built in Java and released as an executable JAR package by a developer who passed away a couple of years ago. Since then, there has been minimal need for even looking at that code, let alone making any changes. That's been really good because I do my programming in VB.NET (Visual Studio) and, while I can read and make sense of Java code, I'm not proficient in actually writing/debugging that code.
However, a recent issue has come up that forced me to try to take a look at this Java code due to some internal changes in organization and data structure. I've looked in his "src\" directory and found older versions of his original code but wasn't able to find the most recent version anywhere. I found some code that made it possible for me to extract the JAR that's currently being used to a local directory on CodeProject (JarsVB), so I've been able to look over some of the .java files when trying to figure out what query is being used for some random operation. I don't know what tool(s) the original developer used to create the project/JAR, so I've installed the IntelliJ IDEA Community Edition 2018 as an IDE, and it's worked for me so far to simply view the code so I can understand a bit about what it's doing.
PROBLEM/GOALS
Unfortunately, now there is a need for me to make a change to the Java code and update the JAR, and this is where I can't seem to make heads or tails of what I need to do. I have my local copy of the code from the "unzipped" JAR containing all the .java and .class files (along with all the other resources), but I'm not sure how to go from that to modifying the code and recompiling the executable JAR.
So, my goals here are as follows:
(properly) Decompile the existing executable JAR. (If the JarsVB solution I mentioned above did what it was supposed to do, I should already have this part handled, but if there's a better, more "integrated" way of doing it, I'd be open to that as well.)
Modify one or more .java files. (I believe I can figure out the syntax well enough to get this part done.)
Debug/test my changes.
Recompile the changes into an updated executable JAR for release. (THIS is where I'm experiencing the most confusion.)
WHAT I'VE DONE
I've been looking at the documentation for IntelliJ to try to figure out how to make this all happen, but I feel like I'm missing stuff. I set my "Project Structure" settings to point to a specific folder, but I can't seem to get it to actually build anything in my specified path.
I went into one of the .java files and made/saved a small change to test, then went to the Build menu and tried all the building options available to me: "Build Project", "Build Module", and "Rebuild Project". Each time, the event log shows that "All files are up-to-date" (even though I changed one), so I go to my output directory to see what it built, but the folder is empty.
I looked at the IntelliJ documentation for Packaging a Module into a JAR File, which says to
On the main menu, choose Build | Build Artifact
But that option is disabled in my Build menu, and when I look in the Project Structure dialog, the Artifacts section is empty, so I try to add a new setting (Add -> JAR -> From modules with dependencies...), but I'm not sure how to properly set that up either.
I tried to select a Main Class from my classes/ directory, but it wouldn't actually accept any of the .class files I selected, so I just left it blank. Then, I did a search for a MANIFEST file, but couldn't find one anywhere so I left that blank as well. The Build menu option is enabled now, but when I tried to Build Artifact, again, I get nothing in my output directory. In fact, the only files I can find that have changed are in my local working directory. I'm just dumbfounded at this point.
FINAL THOUGHTS/QUESTIONS
I've tried to provide as much detail here as I could think of about all the things I've tried and gone through to get this JAR updated, but if there's a question about anything, please let me know. I'm not looking for a "handout" and I don't expect anyone to do this for me, but I'm also not wanting to become a Java developer just for the sake of making some minor changes to an application that will eventually be replaced by a .NET application. I simply am not familiar enough with the tools or Java development in general to know how to get to where I want to be from where I am.
My decompiled source files are in a totally separate directory from the original, production JAR file because, when I recompile this time, I want to completely recreate the JAR. Am I understanding the Java development process correctly in editing one of the .java files I got from decompiling with the JarsVB and then recompiling the JAR?
Thanks in advance for any assistance in finding the resources I need to accomplish these goals.
EDIT/UPDATE
So, looking at the link in the accepted answer in another SO question, How to build jars from IntelliJ properly?, I figured out at least one part of my issue: Leaving the Main Class setting of my Artifacts configuration blank was a problem. Since I hadn't been able to select a .class file and I wasn't sure how to correctly populate that field, I hadn't given the IDE enough information to operate correctly. I entered the namespace and class (namespace.class) I found in the class file that apparently defines the main method for the application, then set the path for the MANIFISET.MF file to my output directory and tried again to Build Artifact.
This time, at least, it DID produce a JAR in my defined output directory, but it's only 1KB in size. As stated above, the source files are in a completely separate directory from the original JAR file from which they were decompiled. The output directory, too, is completely separate from the location of the original JAR file. Do I need a copy of the original JAR file in the output path for recompiling to work correctly?
I'm making progress, but I'm sure I'm overlooking something "stupid" at this point that's primarily due to my unfamiliarity with the IDE and developing Java applications in general.
UPDATE 2
Looking at another SO question - how to create jar of java package in intelliJ idea - I learned that I have to individually add the necessary files for repackaging into the JAR. However, this brings up the question, what files do I add? The linked question identifies the .class files, but when I go look at the .class files in my working directory, none of those have been updated recently, so it looks like I'm still missing a step somewhere.
Another question this brings up is, are there certain conventions for Java development of which I need to be aware when preparing my environment? I have my output path set to a completely separate folder than any working or production code, so I'm wondering if something in that setup might potentially cause issues.
As I said before, I made a small change to one of the .java files, then tried both the Build Module and Rebuild Project options, but those are still telling me that "All files are up-to-date". Even so, I tried adding just the .class files from under my classes\ directory to my Artifact configuration and tried again to Build Artifact. I got a bit larger file (approx. 5MB), but when I try to execute the JAR, it just doesn't appear to do anything, let alone actually launch the application.
I tried again by adding the root folder of my local copy of the source adding everything the root folder contains. (yes, the directory probably needs some "spring cleaning", but that's for another day)
This time, I got a much larger file this time (approx. 21MB), so I thought I might have fixed the problem. Unfortunately, no such luck. The JAR still doesn't appear to execute.
For reference, the original JAR file from which the code was decompiled is approx. 59MB in size so, either IntelliJ is doing an incredible job with compression, or there's yet another step I haven't yet found. I'm sure this is all a matter of getting my IDE configured correctly, but I just can't seem to find the right combination of settings.
This one I couldn't find a proper answer.
I have 2 folders. One is called 'src', where
my java source code is located. The other one
is called 'srcGenerated' and has a set of files
created by a code generator. srcGenerated is a
superset of src.
I want to use both folders as my build path on
Eclipse. The problem is the duplicated files in
srcGenerated. Since there is no way to supress
the generation of files that are already in src,
my question is, how to delete the duplicated files
in srcGenerated based on the existing set of files
from src.
Ant or Powershell script preferred.
May not be the easiest one, but this is what I though of.
You can exclude Java files from srcGenerated that you don't want to be included while building.
Here you can exclude all the files that you don't want to be built. I know, it's painstaking if there are hundreds of conflicting Java files. But it definitely works.