Classpath in JAR manifest? [duplicate] - java

This question already has answers here:
Including dependencies in a jar with Maven
(16 answers)
Closed 5 years ago.
I'm trying to develop a plugin for an FOSS application written by someone else. All I need to do is take a single class I've written, package it in a JAR file, and copy the JAR file to a directory in a pre-existing installation of the application.
When the application sees my JAR file, it should load it on startup.
Problem is, it doesn't seem to be able to load my JAR file.
According to their docs, my manifest may need a CLASSPATH specified.
My JAR file structure is simply: MyJarFile.jar/MyClass.java
It's literally just a JAR file with a single JAVA class file inside it.
I'm new at this, and all the manifest file examples I'm seeing on Google seem to reference other JAR files.
Do I even need to have a CLASSPATH in the manifest?
If so, how do I reference MyClass.java?
I'm using IntelliJ and Maven (for the first time).
Thanks.

Check out the article "Setting an Application's Entry Point" in the java docs:
https://docs.oracle.com/javase/tutorial/deployment/jar/appman.html
You need to add a line to the manifest like "Main-Class: MyClass" if you haven't already in order to run the jar.
Do you need to reference classes from another JAR from within your JAR?
If so, you will need to add to the JAR's classpath. See https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html for how to do that.
In general, I would suggest reading the java docs info on JARs
https://docs.oracle.com/javase/tutorial/deployment/jar/index.html
If you still need help after reading that, please explain your specific use case in more detail, e.g. share actual code or error messages

Try this: Click "File" -> "Project structure" -> "Artifacts" -> right click your jar file and choose "Put into output root"

Related

Images not appearing in JAR file after creating it using eclipse [duplicate]

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.

How can I set my JAR file class path to use an outside folder for dependencies?

I am making a java web application that a hosting service is running for me, and I must recompile and send it to the host every time I make a change. I would like to be able to put all of my libraries in a folder in the host, and only have to compile my jar that will know that its dependencies are next to it.
I have used the IntelliJ IDEA builder located in File > Project Structure. I export all library jars used in a folder next to the main jar named lib, and I have learned about wildcards so I set the classpath to be \lib\*. This did not work and I was thrown a chunky NoClassDefFoundError in my server's console.
I know this must be possible. How should I change my approach?
EDIT: I have researched a bit deeper, and the answer to this question states at the bottom that the wildcard system is not honored in the jar manifest attribute. Do I have to include all files individually (And if so, how?) ?

How do I import an external jar file and a separate file as a command line argument in Netbeans?

I'm having difficulty with my latest programming project. I have a program in Netbeans which relies upon an external library contained within a jar file. I am expected to use several imports to get the operations I need. While that's all fine and dandy, it also means I can't debug this code to make sure it works. I did see something on StackOverflow about doing a copy-pasta on the jar file into my code, but it uses so many commands and so much code that it would be more helpful to import the whole jar file, if possible.
How do I get Netbeans to recognize that I have an external jar file somewhere that it needs to read from in order to get its information?
Furthermore, I am expected to read in a file via the args[], and I am not sure how to read in command line arguments in Netbeans. How do I do this, and where am I expected to put the file to be read in?
I have figured out my issues and am going to answer this for future reference to anybody with this exact same problem. When you have a NetBeans project, you can open the project hierarchy and get a list of your source packages, test packages, libraries, and test libraries. The Libraries folder is where I needed the jar file.
I can right click on the libraries tab to add a jar/folder. Doing so gave me a file explorer to navigate to where I had my jar saved, and adding it fixed all the warnings for external library imports. The program now knows where to look for all the external libraries. Presumably, I'd have to repeat this if I ever moved the jar file.
As for adding the arguments, I found this under Run>Set Project Configuration>Customize. This brings up a window with the project properties. One of the text boxes will be for "Arguments," and filling this in with your commands will give you those commands as your Args[].

My jar resource files in intellij are read only and I need to edit them

I have tried unsuccessfully for a few hours now to edit the java files in a jar I am using as a library. I have marked the resource as a content root and as a source root but I am still unable to edit the code in the jars. The project compiles and runs correctly but I need to make an adjustment to a resource file and cannot; I have tried every project structure I could think of. Is it just impossible? All help is appreciated.
It is not recommended to edit JAR files. From the perspective of reproducibility1, it is better to:
Get hold of the source tree for the library
Check it into your version control (or fork it on Github)
Modify and build it
Use the resulting JAR instead of the original JAR
Another approach is to "overlay" the changes you want to make by creating a another JAR with the alternative version of the resources and placing it earlier in the application classpath.
But if neither of those works for you, you can use the jar command from the command line to modify a JAR file:
Use jar -x ... to extract the files to a temporary directory tree
Apply what ever changes need to be made to the tree
Use jar -c .... to create a new JAR from the tree.
Read the manual entry for the jar command for more details. Signing the new JAR with the original keys would be an issue if you are not the original signer, but I doubt that that is relevant to you.
1 - The point is that the next guy maintaining your code needs to know what you did to the library JAR that you "edited", in case he needs to do the same procedure with another version of the JAR. If you do it by hand, he has no choice but to do a forensic comparison of the differences between the original and your edited version. And that assumes that the original JAR can still be obtained. Note that "the next guy" could be you ... in a couple of months or years time, when you have forgotten exactly what you did.

Exported jar finds some files (not all) even though the paths are the same [duplicate]

This question already has answers here:
I'm trying to export a runnable jar in Eclipse, but I need it to include some other files necessary for running my program
(3 answers)
Closed 8 years ago.
When I run my program from eclipse, it shows up fine, the images from Resources\ show up, as do the sounds from the same place, and the text files are found properly. However, when I export my jar, and copy the resources into it with 7Zip, the images will work, but the sounds and the text files can't be found, even though they're in the same folder, with the same path used to find them in my code. I can fix this by putting a folder next to the jar file named Resources, and put everything in there, but I'd like to know why just putting it in the jar file only worked for the images, and how I can get it to work with the text and audio files as well.
An example to show you what I mean:
File inventory = new File("Resources/inv.txt");
threadpath = "Resources/threads.wav";
enemy1 = new Sprite(new Texture("Resources/miniForestGolem.png"));
When I run it in eclipse, all three work fine, but when I export it, and put the resources folder in the jar file, only the image works.
Edit:
I know how to include my resources, and have done so, I'm asking about how/why some of the resources aren't able to be accessed, even after adding them in.
Ok, from your comments we can infer the difference between executing it from eclipse and executing it from a .jar.
From eclipse: it works, because all that new File(...) find an actual file in Resources/
From the .jar: it won't work, since there is no file in a relative ./Resources/ path from the execution path of the application.
The way to make it work is the next:
Make sure Eclipse recognizes Resources/ as a source folder (right-click on project properties, Java Build Path, and add it as a source path)
Look for a replacement for your API methods that, instead of File objects, use InputStreams. Once you have it, retrieve all your resources as InputStreams taken from the classpath. If you are inside MyClass.java, do this: MyClass.class.getClassLoader().getResourceAsStream("Resources/inv.txt"), etc.
What you have achieved by doing this: instead of File objects built on actual operating system files, you will be retrieving InputStreams read straight from your java application classpath. This way, you can package them into a jar, or into a WEB-INF/classes directory inside a web application, or a library folder in some application servers... wherever you like as long as it is into the application classpath. I would do this if I had to package your application in a portable and usable way.

Categories

Resources