IntelliJ IDEA: Jar doesn't load images when run outside of IDE - java

I am using JetBrains IntelliJ IDEA IDE. This is what I used to generate the jar file. Running the jar file from the IDE, everything looks fine.
Running the jar from the terminal, none of the images are loaded.
My feeling is, from reading around on this, that this has something to do with the relative paths used for the images... but I can't figure this out. I've tried various different project folder structures suggested on the JetBrains forums and StackOverflow, to no avail. Everything is fine until I run a jar outside of the IDE.
My current project structure:
How on Earth do I create a jar file that works everywhere?

Ok, so here's what worked for me. I opened the project structure window (Ctrl-Alt-Shift + S) and went to the Modules tab. From there, I could easily select a folder from the list and click to make it a Resource directory. I was then able to access the resources as URL's with
URL imageUrl = ClassLoader.getSystemResource("image.png")
No need to use a path to the image, just it's actual name.ext

Using IntelliJ's resource folders is probably the right way to go.
Simply right click your res folder, go to Mark Directory As and select Resources.
Then you can access files in this folder simply by name (without a res/ prefix.)
Working visual example:

Source and Resource roots are handled differently.
All the files from the Resource directories will be always copied to the output path. As suggested in another answer, one of the solutions is to configure this directory as Resources root. It's the preferred way to get it working.
If you want files from the Source roots to be copied to the output, you have to specify the patterns for the files that will be copied.
If the project is Maven or Gradle based, these patterns have no effect and IDE will use the rules of the corresponding build system to process the resources.

Related

How do I add LWJGL 3.1.1 to netbeans to use in a Java project?

I want to use the Light Weight Java Gaming Library(LWJGL) to my Netbeans so I can use it in my Java application. The only videos that I can find show the zip file that they downloaded with separate src and doc folders inside of it. The zip file that I download has everything in one directory. I went to lwjgl.org/download and clicked on Stable and then Generate Bundle. What am I missing?
I had the same problem recently.
So, to begin you want to go to Tools in the context menu and select Libraries (as shown). Next you can add a new library and name it e.g. LWJGL-3.1.1 confirm with ok. You can find 3 tabs in the current window Classpath, Sources and Javadoc. There you add your jar files accordingly (in the downloaded .zip file you find .jar files with different names like lwjgl-{whatever}-sources.jar or lwjgl-{whatever}-javadocs.jar) make sure you put them in the right place. You have to repeat this process for all of the jar files you want. The javadoc files are not required but recommended. Make sure you also collect all the native .dll files and merge them in a folder called \natives. You find them in these jar files that are called like: lwjgl-{whatever}-{your-OS}.jar.
Once you have finished the setup for your library right click on your current project and choose Add Library.... In the window that pops up you scroll down until you find your library that you have just created and you are almost done now.
Last but not least go to the project settings. Select Run and make sure that you set the classpath in VM options to something like in the image: -Djava.library.path="C:\java_workspace\LWJGL Library 3.1\natives. Now this classpath tells netbeans where your native files are located. Your \natives folder that you should have created in the beginning is where this path should lead to. That's it. This is all you have to do for a setup without the use of maven, gradle, ...
You can test if it is working with the code provided by LWJGL HelloWorld example.
I hope this solved your problem.
Best regards.

Netbeans add an external folder into a project (like Linked Folder on Eclipse)

How can I add an external folder into a Netbeans project? In my case I need to add an images folder from an network drive.
In Eclipse I do this by adding a Linked Folder. What is the similar procedure in Netbeans?
Currently I'm using Netbeans 8 and created a web java project (Ant).
I can do this by adding the folder content on the build ant script or by creating a symbolic link to the specific path. Both operation are time consuming... Probably there is a (hidden) easy way to do this on Netbeans. Help please
Thanks
I would recommend simply making a Resources folder in the same directory as your src folder. Place your images in that folder, and ensure you specify the filepath accordingly when using the images in your Java project, and you should be fine.
If in your Java project you intend on iterating over images or something like that and the images will be changing on the network drive, you can always use some kind of folder synchronization method like using a briefcase. Then you can create a briefcase folder for your external folder within your Netbeans directory, and use something like auto-scanning of resources to ensure your application continues to use the updated folder.
There may be a much simpler way but this method seems feasible IMO.
The only way that I found it was by creating a symbolic link...
To create a symbolic link on windows I followed this tutorial: http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/
Thanks all!
I guess you can go to Project Properties --> Sources --> Add Folder
here you can select your folder to add..
I created a folder with the same name and the same path as the one I needed from the remote server, then right click and Download.

How to Make Java .jar files be automatically found in any environment

I am trying to add an external library to my Java project. The library files are in .jar format, and every time someone tries to run the project in a different environment, they have to modify the build path so that their environment can find the .jar files.
Is there any way to make it so that the .jar files are automatically found by the build path? Maybe by specifying where in the project the .jar files are located?
Edit: Here is an example -
In my linux environment, the .jar files are located in:
/home/MyUsername\SomeDirectory\workspace\java_project_name\data
In my windows environment, the .jar files are located in:
C:\MyUsername\SomeDirectory\workspace\java_project_name\data
In the example above, the project root directory is "java_project_name", and the .jar files are always in the java_project_name\data folder. Even though this is the case, different environments can't seem to detect that it is always in the same path in relation to the project's root directory.
I have looked in many places on how to do this, and some people told me it isn't possible. This doesn't sound reasonable to me, which is why I am posting this question here.
Thanks in advance for your help!
you can add a ClassPath: entry in your manifest file of the main jar, and use relative paths. As long as the jars are found relative to the main jar it will work.
This issue was one of my main motivators to start using maven.
#YoK nicely quotes here the relevant reasons to this question https://stackoverflow.com/a/3589930/1493954
Here is one the relevant quotes from Benefits of using Maven
Henning
quick project setup, no complicated build.xml files, just a POM and go
all developers in a project use the same jar dependencies due to
centralized POM.
getting a number of reports and metrics for a project
"for free"
reduce the size of source distributions, because jars can
be pulled from a central location
This is a common problem for developement environments.
I myself use the following solution in netbeans [Hope so that it works in your IDE too]:
Create an Ant variable [for e.g. JAR_LOCATION].
Each and every JAR that you refer, must have it's location relative to JAR_LOCATION.
Now, in every development environment that you're gonna use, you can set up the same ANT variable and it'll automatically pick up the JAR.
You can see the example in the given snapshot of netbeans..

Exporting Images with JAR in Eclipse (Java)

I've been working on a little project that requires external images for display. I'm not all that familiar with how to use Eclipse and this is my first time attempting to export a completed project so I can share it with others. Right now, it seems the only way I can get my images to show up is if I assign a specific folder on my hard drive and have the image paths in the code go to that.
I'm looking for a way to export the images as part of my JAR or as part of the same package so when I go to send this program to other people, I don't have to send them a separate archived folder of images. I'd also be interested in learning what I need to do to have my code reference the images within that package so they'll work without an external folder.
I have read about some kind of package system within Eclipse, but have thus far had no luck in figuring out how to use it. Could use some explicating!
Thanks in advance to anyone willing to give me their two cents.
Something I would have found useful with this answer is the following: make sure you put your images/files in the same eclipse folder (or sub-folder below) as your source code. I created a folder "images_ignored" using eclipse, added it to the build path but still it refused to be included in my JAR file (when creating an executable JAR).
Just drag the images folder into your Eclipse project, then choose to "Copy New Folder" or "Copy File and Folder" depending on Eclipse version, and then right click on the image folder (in Eclipse) and --> build path "use as source folder".
you might need to load them as class path resources if they are within a jar. see: getClass().getClassLoader().getResourceAsStream(...)
Use getResource() to load the images:
ImageIcon qmarkIcon = new ImageIcon(getClass().getResource("images/mark.gif"));
If you're using JDK 1.7 or JDK 1.8, you might want to use the NIO.2 API.
for (FileSystemProvider provider : FileSystemProvider.installedProviders()) {
if ("jar".equals(provider.getScheme()))
return provider.newFileSystem((new File(Start.class
.getProtectionDomain().getCodeSource().getLocation().toURI()))
.toPath(), new HashMap<String, Object>());
}
If you enter this code into a method that returns a java.nio.file.FileSystem, you can call the method to get the FileSystem for the JAR file.
To get the path to access the files inside your JAR file, you can use the following method, which then allows you to read the files however you may want.
fileSystem.getPath("/images/image.gif")
If you would like to be able to run this in Eclipse, make sure you surround the call to the method with a try/catch IOException and assign to your FileSystem object the following.
new File(Start.class.getProtectionDomain().getCodeSource().getLocation().toURI())
.toPath().toString();
This will allow you to run your program whether it's compressed into a JAR file or not.
I recommend you get used to using NIO.2, since it is a very powerful API.
If you add a folder to build path you can retrieve the images either in eclipse and when you exported it in jar file, just remember to don't reference the image with the path like img/myImage.gif but only myImage.gif !

Add a properties file to IntelliJ's classpath

I'm running a simple Java program from the IntelliJ IDE using the Run->Run menu. It works fine. Now I want to add log4j logging.
I added a resources folder under my project root.
I added a log4j.properties file in that folder.
I changed the code to log something.
What is the right way to tell IntelliJ to include the resources folder in the classpath so the properties file is seen?
With IntelliJ 8 I could guess like a drunk monkey and eventually get it to work. I have 9 now and I am wholly unsuccessful. I've been trying for an hour. How about an "Add to classpath" option somewhere? /fume /vent /rant
Try this:
Go to Project Structure.
Select your module.
Find the folder in the tree on the right and select it.
Click the Sources button above that tree (with the blue folder) to make that folder a sources folder.
Actually, you have at least 2 ways to do it, the first way is described by ColinD, you just configure the "resources" folder as Sources folder in IDEA. If the Resource Patterns contains the extension of your resource, then it will be copied to the output directory when you Make the project and output directory is automatically a classpath of your application.
Another common way is to add the "resources" folder to the classpath directly. Go to Project Structure | Modules | Your Module | Dependencies, click Add, Single-Entry Module Library, specify the path to the "resources" folder.
Yet another solution would be to put the log4j.properties file directly under the Source root of your project (in the default package directory). It's the same as the first way except you don't need to add another Source root in the Module Paths settings, the file will be copied to the output directory on Make.
If you want to test with different log4j configurations, it may be easier to specify a custom configuration file directly in the Run/Debug configuration, VM parameters filed like:
-Dlog4j.configuration=file:/c:/log4j.properties.
I have the same problem and it annoys me tremendously!!
I have always thought I was surposed to do as answer 2. That used to work in Intellij 9 (now using 10).
However I figured out that by adding these line to my maven pom file helps:
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
...
</build>
I spent quite a lot of time figuring out how to do this in Intellij 13x. I apparently never added the properties files to the artifacts that required them, which is a separate step in Intellij. The setup below also works when you have a properties file that is shared by multiple modules.
Go to your project setup (CTRL + ALT + SHIFT + S)
In the list, select the module that you want to add one or more properties files to.
On the right, select the Dependencies tab.
Click the green plus and select "Jars or directories".
Now select the folder that contains the property file(s). (I haven't tried including an individual file)
Intellij will now ask you what the "category" of the selected file is. Choose "classes" (even though they are not).
Now you must add the properties files to the artifact. Intellij will give you the shortcut shown below. It will show errors in the red part at the bottom and a 'red lightbulb' that when clicked shows you an option to add the files to the artifact. You can also go to the 'artifacts' section and add the files to the artifacts manually.
Faced a similar challenge adding files with .ini extensions to the classpath. Found this answer, which is to add it to Preferences -> Compiler -> Resource Patterns -> [...] ;*.ini
If you ever end up with the same problem with Scala and SBT:
Go to Project Structure. The shortcut is (CTRL + ALT + SHIFT + S)
On the far left list, choose Project Settings > Modules
On the module list right of that, select the module of your project name (without the build) and choose the sources tab
In middle, expand the folder that the root of your project for me that's /home/<username>/IdeaProjects/<projectName>
Look at the Content Root section on the right side, the red paths are directories that you haven't made. You'll want to put the properties file in a Resources directory. So I created src/main/resources and put log4j.properties in it. I believe you can also modify the Content Root to put it wherever you want (I didn't do this).
I ran my code with a SBT configuration and it found my log4j.properties file.
For those of you who migrate from Eclipse to IntelliJ or the other way around here is a tip when working with property files or other resource files.
Its maddening (cost my a whole evening to find out) but both IDE's work quite different when it comes to looking for resource/propertty files when you want to run locally from your IDE or during debugging. (Packaging to a .jar is also quite different, but thats documented better.)
Suppose you have a relative path referral like this in your code:
new FileInputStream("xxxx.properties");
(which is convenient if you work with env specific .properties files which you don't want to package along with your JAR)
INTELLIJ
(I use 13.1 , but could be valid for more versions)
The file xxxx.properties needs to be at the PARENT dir of the project ROOT in order to be picked up at runtime like this in IntelliJ. (The project ROOT is where the /src folder resides in)
ECLIPSE
Eclipse is just happy when the xxxx.properties file is at the project ROOT itself.
So IntelliJ expects .properties file to be 1 level higher then Eclipse when it is referenced like this !!
This also affects the way you have to execute your code when you have this same line of code ( new FileInputStream("xxxx.properties"); ) in your exported .jar.
When you want to be agile and don't want to package the .properties file with your jar you'll have to execute the jar like below in order to reference the .properties file correctly from the command line:
INTELLIJ EXPORTED JAR
java -cp "/path/to_properties_file/:/path/to_jar/some.jar" com.bla.blabla.ClassContainingMainMethod
ECLIPSE EXPORTED JAR
java -jar some.jar
where the Eclipse exported executable jar will just expect the referenced .properties file to be on the same location as where the .jar file is
Right-click on your directory and from Mark directory as select Resources root as below:
Perhaps this is a bit off-topic, seeing as the question has already been answered, but I have experienced a similar problem. In my case only some of the unit test resources were copied to the output folder upon compilation. My persistence.xml in the META-INF folder got copied but nothing else.
In the end I "solved" the problem by renaming the problematic files, rebuiling the project and then changing the file names back to the original ones. Do not ask me why this worked but it did. My best guess is that, somehow, my IntelliJ project had gotten a bit out of sync with the file system and the renaming operation triggered some kind of internal "resource rescan".
This is one of the dumb mistakes I've done. I spent a lot of time trying to debug this problem and tried all the responses posted above, but in the end, it was one of my many dumb mistakes.
I was using org.apache.logging.log4j.Logger (:fml:) whereas I should have used org.apache.log4j.Logger. Using this correct logger saved my evening.
I had a similar problem with a log4j.xml file for a unit test, did all of the above. But figured out it was because I was only re-running a failed test....if I re-run the entire test class the correct file is picked up. This is under Intelli-j 9.0.4

Categories

Resources