Java getResource is in wrong path - java

I hope someone can help me here, becouse I'm fighting with a problem for some time. In my main class I use this command:
System.out.println(getClass().getClassLoader().getResource("org"));
The problem I've got is that it returns:
file:/E:/Tmp/ExamplePr/PROJEKT/proj/build/classes/java/main/org
instead of:
file:/E:/Tmp/ExamplePr/PROJEKT/proj/build/resources/java/main/org
The problem is that it goes into classes directory instead of resources dir. As a result I can't have access to my .fxml files I need. I'm using gradle for build and currently working with JavaFX. I've tried something like:
System.out.println(getClass().getClassLoader().getResource("/resources/java/main/org"));
But I just got null :(
Do you know any method to force him to use absolute path or to look for resources in resource filder or even use something like to use "../" from linux to go up. I dodn;t find any of this

The root of your resources tree is defined by the classloader (as described in the JavaDoc). You can define the root by explicitely setting it in your classpath or preferably by using a build tool like maven and following the conventions set and used by the tool. For maven projects the root would usually be at main/java/resources.

getResource will always return the first match in the class path. So if you specify E:/Tmp/ExamplePr/PROJEKT/proj/build/resources/java/main before E:/Tmp/ExamplePr/PROJEKT/proj/build/classes/java/main in your classpath, you will get what you want.
That said, the resources are usually meant to be copied with the classes, and sometimes both are packed in a jar file, so you shouldn't worry about it.

With JavaFX use FXMLLoader;
FXMLLoader.load(new URL(getClass().getResource("/fxml/myfxml.fxml").toExternalForm()));
Make sure to pass the platform appropriate separator and use a relative path.

Related

Ressources can't be found in maven build

I wanted to migrate my local prototype to a maven build and start getting productive. But unfortunately when calling
loader.setLocation(getClass().getResource("views/TaskWindow.fxml"));
On runtime it seems that maven doenst find the ressource xmls.
I tryed "TaksWindow.xml", "../views/TaksWindow.xml" "views/TaskWindow.xml" and "/views/TaksWindow.xml" but somehow it always gives me "no location set" error.
My project structure looks like this:
Any ideas why?
The path you specified is a relative path. Which means the classloader will look for a views folder at the location of the class (i. e. its package). You propably want to use an absolute path.
Try the following code, notice the leading /.
getClass().getResource("/views/TaskWindow.fxml")
For more information, see this answer.

How to set the absolute path of .so files?

I am loading the JNI libraries using System.loadLibrary("xyz") and it works fine. But the thing is, when using java.lang.System.load() to load a library, an attacker can replace or modify the original file with a malicious one if the full path of the dynamic library is specified in a world readable location (such as the SDCard). This can result in the loading of untrusted content into the Dalvik VM.
So this can be fixed using fully qualified path to the target library. For some reason I am not able to get succeed in providing fully qualified path.
Below are the things I tried but no luck.
System.load ("xyz")
System.load ("/src/main/jni/lib/xyz")
System.load ("/system/lib/xyz")
Can someone please suggest where I am going wrong.
You need to set the 'jniLibs.srcDirs' in the gradle file.
Something like:
main {
...
jniLibs.srcDirs 'lib'
}
I have the same problem with you.
When load a lib in java.library.path(located in /data/data/com.xxx.yyy/lib/[abi]), System.loadLibrary is OK.
But when load a lib from a absolute path, we should use System.load. For example:
System.load("/data/data/com.xxx.yyy/files/xxx/libxyz.so")

Same code behaving differently on two different packaging

I have a set of codes which are common for two different products, but a part of the code is behaving differently for each product
URL wsdlURL = IntegrationLandscapeService.class.getClassLoader().getResource("IntegrationLandscapeService.wsdl");
For One set up it is giving absolute path and for the other its giving relative path and this is leading to problems, my requirement is to get absolute path for the issue.
Packaging:
Code flow:
The call is made from the Main Class File and from there CommonCode in common code it is looking for the WSDL located in LandScapeService.jar
Update:
The next line of the code is
IntegrationLandscapeService landscapeService = new IntegrationLandscapeService(wsdlURL);
but I get the below error
failed [Failed to access the WSDL at: jar:file:/
tracker.jar!/lib/t24-IF_IntegrationLandscapeService-IntegrationLandscapeService-jwc.jar!/IntegrationLandscapeService.wsdl
.It failed with:
\tracker.jar (The system cannot find the file specified).]
Screen Shot of Jar
The error shows two '!' in the path which indicates the resource is in an embedded/nested/inner jar-file. A product that uses the fat/bundled-jar approach (where one jar-file contains other jar-files) will need some trickery to load classes and resources from the embedded jar-files. You can read about it at http://www.jdotsoft.com/JarClassLoader.php (*)
In any case, there is not much you can do about it since loading resources from embedded jars is not supported natively by Java. The implementation providing the "trickery" I mentioned above will need to fix that (and some do it better than others, see the link above).
The other product with a Par-file indicates the use of OSGi which only requires proper configuration to keep resource-loading working. There is an answer here that explains your situation and solution options.
(*) Spring-boot also has some good documentation and a solution, but I have not tried using the solution with a non-Spring application. See https://docs.spring.io/spring-boot/docs/current/reference/html/executable-jar.html for more information.
You can use getAbsolutePath
File file = new File(url.getPath());
String path = file.getAbsolutePath();
Isn't that what you are looking for?
This is because the files inside the JAR are not treated as regular files, as they are not expanded and not available directly to file explorer.
In Jar, if the files are referred, you will get the path from the root of the JAR file.
Please make sure you have the classpath entry for the Jar location. This will help to find the resource. Otherwise, try the following code(not sure whether it will work in your case, give it a try).
String resource = "/com/example/IntegrationLandscapeService.wsdl"; //package structure of the file
URL res = IntegrationLandscapeService.class.getResource(resource);
Refer this answer to understand more Stack Overflow comment

Intellij can't find .png

My intellij can't find local .png images.
private String craft = "craft.png";
ImageIcon ii = new ImageIcon(this.getClass().getResource(craft));
The .png is located in the same directory as the java files. I don't understand why it isn't working. Using maven build, tried alternating from resources to java, but still no luck :(
craft.png must be placed into src/main/resources, otherwise it will be not copied to the classpath according to the Maven rules. See this answer for more details.
Your code should be also changed to:
private String craft = "/craft.png";
Here is the sample working project.
Go to your IntelliJ Preferences and search for "resource patterns" (or just go straight to the "Compiler" settings).
IntelliJ will only copy certain resources to the output directory. Make sure the resource pattern includes *.png.
I have my resource pattern set to !*.java (copy everything that's not a source file) which seems to work fine (and should really be the default, in my opinion).
tried alternating from resources to java
So at first you tried putting craft.png into src/main/resources. That is where it must be put according to Maven (not in src/main/java).
But it didn't work because
this.getClass().getResource("craft.png") tries to find "craft.png" relative to the this.class's package. If your this.class is in package foo.bar then you must put craft.png in src/main/resources/foo/bar/
You can also provide an absolute path in getResource() by using a leading slash /. For example put craft.png into a custom folder under resources src/main/resources/customFolder/ and read it with the leading slash / in front of customFolder:
this.getClass().getResource("/customFolder/craft.png")
If you don't use leading slash in getResource() method then internally class's package name is prepended to the resource name to make it absolute.
This behavior is explained in Class.getResource()

How to get a resource in another jar

I have a jar embedded in a bundle that needs to fetch a resource packaged with it like so:
MyBundle
-\ src
-\lib
-\MyEmbeddedJar
-\src
-\SomeClass
-\someResource.xml
I am trying to access 'someResource.xml' from 'SomeClass' like so:
SomeClass.class.getResource( "someResource.xml" );
But I've had no luck. I've tried several variations with the CWD appended (eg: './someResource.xml') but I just can't get this resource to load.
I know that the "right" way is to use Activator to get hooks back to the proper classloader, but the embedded jar can be used in other projects, so I'd hate to have to add OSGi specific code to it just to get it to play nice with OSGi.
Is there any other way to load resources in OSGi agnostically of OSGi?
I Assume that SomeClass is inside the embedded jar (say, somejar.jar), and someResource.xml is in the outer jar, in a lib directory.
In this case, there is no way to get to that in a non-OSGi context. Let's look at both situations in isolation.
In OSGi
Your someResource.xml should very well be reachable using the regular (non-OSGi specific) resource loading mechanisms, provided that it is reachable from the Bundle-ClassPath. For instance, if you have the following manifest header,
Bundle-ClassPath: ., somejar.jar
you will be able to get to your resource using "lib/someResource.xml".
Notice the dot on the classpath: this means you can reach classes and resources from the root of the jar. If you forget that, you will only be able to get to classes and resources inside somejar.jar.
Not using OSGi
If you're not using OSGi, there is no (reasonably simple) way to get to classes and resources inside of the inner jar that I know of.
Your options
Depending on what you want your bundle to look like, you have two options now.
Is it really necessary that SomeClass is in an embedded jar? If so, you're at a loss, and you jar will only work using OSGi.
If you have the option to 'unpack' somejar.jar into your jar, you subvert the problem, and your jar can work in both situations.
Personally, I'd pick option 2.: unless you have resources that might overwrite each other when you 'merge' the jars, it is no problem at all to have a slight mess of resources inside your bundle.
My assumptions are that:
That I'm not quite sure I get how your description of the problem matches the diagram. Where is the *.jar file?
The bundle that is attempting to
access the embedded jar is the same
bundle that contains the embedded
jar.
Per the OSGi agnosticism, I am
assuming that the embedded jar is
not explicitly exposed as part of
the current bundle's classpath and
that it is not loaded as another
OSGi bundle.
If the jar in question is itself a resource of the current classloader, then you would first need to get the jar as a resource or as an InputStream, such as with MyBundleClass.class.getResourceAsStream("/pathToJar.jar"); then wrap it with a java.util.jar.JarInputStream. Then, continue to call getNextJarEntry() until you find the JarEntry object where "someResource.xml".equals(jarEntry.getName()).
I'm going to accept #Angelo's solution as it gave me the idea on how to work around this, though, I'd like to add more information in - thus my answer.
My work around was to add another constructor to SomeClass that takes in a java.net.URL instance. I also copied someResource.xml into the bundle's root.
I then updated the instantiation of SomeClass in the bundle like so:
new SomeClass( FileLocator.find( Activator.getDefault().getBundle(), new Path( "./someResource.xml" ), new HashMap< String, String >() ) );
This seems like a pretty big hack to me. What if I could not edit the contents of SomeClass ? I guess I would have to unpack it or I'd be forced to wrap it into it's own bundle?
I'm going to make the following assumption:
embedded.jar
src/SomeClass.class
someResource.xml
and the bundle contains embedded.jar and embedded.jar is on the Bundle-Classpath.
In this situation SomeClass.class.getResource("someResource.xml") will look for a resource on the classpath called src/someResource.xml because SomeClass is in the package src. In order to get someResource.xml in the root of the jar you need to do SomeClass.class.getResource("/someResource.xml") instead.
This isn't OSGi specific though, this is just how resource loading works in Java.

Categories

Resources