Relative filepath to access resources - java

I am quite new to Eclipse 4, RCP and SWT and I am stuck on this issue :
I want to access image resources from code with a relative filepath. Problem is that the default location ./ is set to my home directory /home/name/ (I'm using Ubuntu). I have found that by creating a new File and printing its CanonicalPath.
I am used to having the default location set to the project directory, such as /home/name/workspace/project/, which is, from what I've seen so far, the default behavior in Eclipse / java programs.
I would like to keep this behavior because it seems more reliable to me (after deployment for example).
Note: I have tagged e4, rcp and swt because I'm not sure which one causes the difference.

In an Eclipse plugin (including RCP code) you should use the FileLocator class to find resources within the plugin.
You open a resource as a stream:
Bundle bundle = ... plugin bundle
IPath path = new Path("path relative to plugin root");
InputStream is = FileLocator.openStream(bundle, path, true);
You can also use FileLocator.find:
URL url = FileLocator.find(bundle, path, null);
URL fileUrl = FileLocator.toFileURL(url);
Don't forget to include your resources directory in the build.properties.
If your image is not in the plugin you can't really use relative paths.
In an e4 plugin you can inject the Bundle using #OSGiBundle:
#Inject
#OSGiBundle
Bundle bundle;
(#OSGiBundle requires a dependency on the org.eclipse.e4.core.di.extensions plugin).

Related

UrlClassLoader to load a image resource

I am creating an eclipse workspace starting by a java project (not written by me).
I am facing problems with the following method:
public static URL getURL(String fileName) {
URLClassLoader urlLoader = (URLClassLoader) getInstance().getClass()
.getClassLoader();
URL fileLocation = urlLoader.findResource(fileName);
return fileLocation;
since the findResource doesn't find the JPG resource (filename = "icons/INIT.JPG").
Looking on urlLoader.getUrl, I noticed the class aims only to jar files. Adding the folder icon to the Project->Libraries under eclipse I managed to let findResources look into the icon folder: nevertheless, the image is not a jar file and so it isn't considered.
Honestly, I don't get the point of using this process to load an image, but I cannot change the code and I was hoping in a solution within Eclipse project setup.
Thanks in advance
Based on the answers to my questions in the original comment, there are some facts:
You cannot change the code, and it looks like it's retrieving the AppClassLoader.
Even if you cast it into URLClassLoader, it's still an instance of an AppClassLoader, so it will look for the contents of the classpath and all JAR/ZIP files in JAVA_HOME\lib\ext.
You said that the project is guaranteed to work without to move the file anywhere, so there's only one option: add the file that you want to retrieve with the ClassLoader to the classpath.
Right click on the project, select Build Path and choose Configure Build Path.
Click on Source > Add Folder... and add the folder where the resources that you want to take are.
PD: If you add the folder as Class Folder in the Libraries tab, the JPG image won't be recognised by the AppClassLoader.

Unable to get Image file URL from eclipse plugin project Bundle

I am trying to get image from a bundle in eclipse plugin project. But it always return null. Please find the project structure below. I want to get the URL of an image "icon_4.png" which is under "images/EmailTemplatesOutput/assets/icon_4.png". I have tried different ways. But it returns null.
Project Structure is :
String path = "icon_4.png";
Bundle bundle = Platform.getBundle("BulkDemo");
URL url = FileLocator.find(bundle, new org.eclipse.core.runtime.Path(path), null);
ImageDescriptor imageDesc = ImageDescriptor.createFromURL(url);
Image image = imageDesc.createImage();
Don't put the 'images' directory in the 'src' folder, put it at the top level of the project (like 'bin' and 'META-INF'). Make sure you update the 'build.properties' to include the images folder in the build.
The path for the image is relative to the plug-in root so it will be images/EmailTemplatesOutput/assests/icon_4.png (assuming you move the images directory).
The URL returned by FileLocator.find uses an Eclipse only scheme so can only be used by Eclipse APIs. You can convert the URL to a normal file URL by adding:
URL fileURL = FileLocator.toFileURL(url);
This may cause Eclipse to unpack your plug-in to a temporary location to access the files.

Relative resource paths in Java project in IntelliJ IDEA

I am trying to display an icon in my GUI by using a relative path, as in "display image from resources/image.png". I have tried a million different ways to express this, but nothing works. This makes me think it's a problem with my IntelliJ IDEA settings or project structure. I have set up the "resources" folder as a "resources folder". I don't know what else it expects me to do.
How can I load an icon from a file using a relative path in a Java project within IntelliJ IDEA?
My project structure:
src/main/java/ <-- set as "sources" in IntelliJ
src/main/java/ui/ <-- contains classes for my GUI
src/main/resources/ <-- set as "resources" in IntelliJ. Contains images.
Edit: Able to use relative path to confirm that file is found, not able to load it as icon.
String path = "src/main/resources/image.png";
System.out.println(new File(path).exists()); <-- true
I've encountered this issue many times and what worked for me was using InputStream
InputStream is = Main.class.getClassLoader().getResourceAsStream("name_of_file.png");
Using InputStream will allow you read from various file types. Now to load in the icon you can do
Icon icon = new ImageIcon(ImageIO.read(is));
Resources are on classpath, not on filesystem path - which is taken relative from running directory, which is project directory when you are running it from idea. Usually you will distribute your aplication as jar, and this it is better to load resources from classpath. In zour case - from root directory

Eclipse: Setting an environment variable that references a folder contained in a plugin

I have some Java code that wraps an existing native application and performs the following:
Takes some input from the user
Executes a native application providing as parameters the input taken in step 1
Performs some more operations on the output files produced in step 2
The native application in step 2 requires some dynamic libraries. So, under Run Configurations -> Environment I have set the following variables to reference the libraries.
DYLD_LIBRARY_PATH = ${project_loc}/path/to/libs
DYLD_FALLBACK_LIBRARY_PATH = ${project_loc}/path/to/libs
And so far it all works. Now I have packaged my code and the existing native application as an Eclipse plugin. Whenever I try to run the code inside the plugin I get the following error:
dyld: Library not loaded: libsrcml.dylib
Referenced from: workspace/Project/src/nativeApp
Reason: image not found
To my understanding, this happens because the environment variables I had set previously reference {$project_loc}, which is the location where my Eclipse project was stored. Now, my code is no longer contained in that project, but it is contained inside a plugin, so the path for the variables no longer works. Question is, how can I set a path that references a folder inside my plugin? Alternatively, is it possible to, somehow, load those variables dynamically inside my Java code?
The path variables are used to specify a fixed location in the file system.
To identify a resource in a plugin, I would use its URL
Case 1: Platform.getBundle("").getEntry("")
Bundle bundle = Platform.getBundle("your.bundle.id");
URL url = bundle.getEntry("yourDir/yourFile.txt");
File f = new File(FileLocator.resolve(url).toURI());
Case 2 : Platform URL to your resource:
url = new URL("platform:/plugin/your.bundle.id/yourDir/yourFile.txt");
File f = new File(FileLocator.resolve(url).toURI());
Thanks to Vogella for this tip.
However, for libraries in your plug-in it is a little bit different, as System.loadLibrary("libname") must be able to resolve your lib.
If you ship and use native libraries in your plug-in, please package your plugin as a directory, and not as a compressed jar file.
So edit your plug-in's MANIFEST.MF and set your Eclipse-BundleShape: dir
Eclipse-BundleShape: dir
Then, your plug-in will be packaged as a folder, and then it is your responsibility to make your Native libraries interacting. Usually this depends on how the native libraries are linking each other, and on how your Java-to-native framework is setting the search paths.
My simple solution, is putting all the native libraries to the root folder of the Eclipse executable, which is the Java execution directory, so that I can get that path using the "user.dir" environment variable as follows:
System.getProperty("user.dir");
Then, when all the natives are in the same folder, they can reference each other without problems.
Please, also check these resources:
this StackOverflow answer
this eclipse forum answer

How to copy jar in libs folder using Intellij plugin development APIs

I am developing intellij plugin, on click of menu option it should copy jar to libs folder of select project. kindly provide any link or code how I can implement this.
jar is on this path "project_name\resources\raw\xyz.jar" and using below code to get that jar as inputsream but getting "NULL"
ClassLoader CLDR = this.getClass().getClassLoader();
InputStream is = CLDR.getResourceAsStream("raw/xyz.jar");
Try something like this:
PluginId runtimePluginId = PluginManager.getPluginByClassName("com.company.AnyClassInYourPlugin");
IdeaPluginDescriptor runtimePlugin = PluginManager.getPlugin(runtimePluginId);
File yourJar = new File(runtimePlugin.getPath().getAbsolutePath(), "your-file.jar");
Given any class that's contained in your plugin, the API allows you to retrieve a plugin descriptor for that plugin, which then allows you to get the absolute path to the plugin or any jar related to it.
See this real example of how to retrieve a JAR embedded in a plugin.

Categories

Resources