How to set the absolute path of .so files? - java

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")

Related

Relative path for library exporting in Java

I'm trying to export a .JAR to be used as library to other projects. The problem is that I need to use relative paths when referencing files inside this library, but the only solutions I found were using absolute paths like:
private static final String FILE = new File("").getAbsolutePath().concat("/src/bla/file.txt");
Obviously whenever I try to run this line of code as an exported library I'll get something like DRIVE/project/src/bla/file.txt which is not correct since this .JAR can be anywhere inside DRIVE/projects like DRIVE/projects/lib/myLib.jar.
In Nodejs we had easy functions to retrieve relative paths according to the runtime location. How can I reference files in such a way that it will capture the "runtime path" so that I can safely reference them and the path will be dynamically solved?
For those who are so eager to mark this question as duplicate, please read with attention first. I'm NOT asking how to READ files from resources!
To use the "file.txt" present in the classpath,we need to make sure the "file.txt" is present in the directory represented by classpath.
Assume you have all the class files generated in a directory named "/home/abcuser/target".
For simplicity we will place the file.txt in the target directory root level.
The main class is say TestFileAccess.class(the class with the main method)
To execute the main class present in the target directory you can use the below command
java -cp /home/abcuser/target TestFileAccess
Now, the classpath in this case is /home/abcuser/target
To access the resources on classpath,you can go with two ways.
ClassLoader.getSystemResource and ClassLoader.getSystemResourceAsStream methods.
Class.getResource and Class.getResourceAsStream
The main difference between the ClassLoader and Class versions of the methods is in the way that relative paths are interpreted.
The Class methods resolve a relative path in the "directory" that corresponds to the classes package.
The ClassLoader methods treat relative paths as if they were absolute; i.e. the resolve them in the "root directory" of the classpath
Using ClassLoader you can use the below snippet
InputStream inputStream = ClassLoader.getSystemResourceAsStream("file.txt");
To explicitly reference a resource as a classpath file you can add the resource path to the classpath while executing the java code.
Let's say your resource "file.txt" is in /home/abcuser/resources.
You can add the the resource path to the classpath during the java execution start as shown below
java -cp "/home/abcuser/target:/home/abcuser/resources" TestFileAccess

Java getResource is in wrong path

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.

ClassLoader loading the wrong instance of a file

So I see there has already been a post very similar to this issue, however I am in a situation where I have no power to specify the location of this file within my jar and so am hoping someone is aware of a solution to get around this.
So I currently use the following snippet to obtain a file as an input stream, the file 'plugin.xml' is located at the root of the jar and I cannot change this location as another piece of software (dynatrace) creates this file and determines its location.
the standard snippet:
InputStream is = JmxPlugin.class.getResourceAsStream("/plugin.xml");
Now I am aware that the issue is that the ClassLoader is picking up the first file which matches the name 'Plugin.xml' along the classpath (one which isn't in my jar, yay).
Can anyone think of a way to ensure I pick up the correct file without having to move it? The relative path of my class in the jar is com/something/jmx/JmxPlugin.class.
(Id rather not have to unpack the jar in memory).
Many thanks for any contributions,
I'm not absolutely sure, but seems like Thread.currentThread().getContextClassLoader().getResourceAsStream("/plugin.xml") may solve your issue. If not, you'll have to create your own ClassLoader and resolve the issue there.
The simplies way is to move your jar in classpath to be the first containing Plugin.xml,
Another approach is to use getResource() to locate your jar file:
URL myJar=JmxPlugin.class.getResource("/"+JmxPlugin.class.getName().replace(".","/")+".class");
then use this URL to open jar file and extract Plugin.xml.

Add images to jar

I want to set icon to my JFrame. I do the following:
Image icon = Toolkit.getDefaultToolkit().getImage("src/images/icon.jpg");
this.setIconImage(icon);
It works fine when I run this code from netbeans, but when I try to run this code from jar file, images are not shown in my JFrame. I have tried to load images as resources:
this.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/src/images/icon.jpg")));
but when I run this code it fails with NullPointerException
Uncaught error fetching image:
java.lang.NullPointerException
at sun.awt.image.URLImageSource.getConnection(URLImageSource.java:99)
at sun.awt.image.URLImageSource.getDecoder(URLImageSource.java:113)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:240)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:172)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:136)
How can I do this work?
edit:
Thanks to all,
the problem was solved by specifying image as
Toolkit.getDefaultToolkit().getImage(getClass().getClassLoader().getResource("images/icon.JPG"))
As for it seems rather weird, and would be better if it was like
this.setIconImage(new ImageIcon(pathToIcon).getImage());
Assuming your JAR file has a top level directory called images, you can use either:
getClass().getResource("/images/icon.jpg") or
getClass().getClassLoader().getResource("images/icon.jpg")
Looking at the source code of URLImageSource, it appears that the reason that getConnection throws an NPE is that it has a null for the url. And that leads me to suspect that
getClass().getResource("/src/images/icon.jpg")
is returning null. It would do that if it could not locate a resource with that pathname.
I bet that the problem is that you've got the path wrong.
To prove / disprove this, you should run jar tvf on the JAR file, and look for the line that matches "icon.jpg". Is the corresponding pathname the same as what you are using? If not, use the pathname from the matching line in the getResource call and it should work. Alternatively, if the file doesn't show up at all, look at the NetBeans build configs that tell it what to put in the JAR file. (I'm not a NetBeans user, so I can't say where you would need to look ...)
If that leads you absolutely nowhere, another possibility is that getClass().getResource(...) is using a classloader that doesn't know about the JAR file containing the image. (This seems pretty improbable to me ...)
getResource() loads a resource from classpath, not an OS path, and the after compilation your classpath will not include the /src folder, but rather just its contents. So you'd better try /images/icon.jpg.
Also you may find this discussion somewhat useful.
This should do it assuming you can import javax.imageio.ImageIO:
Image icon = ImageIO.read(this.getClass().getResource("/src/images/icon.jpg"));
this.setIconImage(icon);
.."/src/images/icon.jpg"..
The '/src' prefix of the address seems suspicious. Many apps. will provide separate 'src' and 'build' directories, but it normally ends up that the 'src' prefix is not used in the resulting Jar. I recommend trying..
.."/images/icon.jpg"..
& also triple checking that the image is in the location of the Jar that the code is expecting to find it.
For this to work, you should access the images from a directory relative to some fixed class.
For example, if the image files are saved in a directory "images" on the same level as the Toolkit.class, then
this.setIconImage(Toolkit.getDefaultToolkit().getImage(Toolkit.class.getResource("images/icon.jpg")));
should work.
You can simply create a package inside the main source, and incluse your images in this package. Then, just call the images in your main class like:
ImageIcon a = new ImageIcon(MainClass.class.getResource("/Package/Image.jpg"));
JFrame f = new JFrame("Edit Configure File");
//Image image = ImageIO.read(getClass().getResource("images/ctx.Icon"));
f.setIconImage(new ImageIcon("images/ctx.PNG").getImage());//this works for me finally
//f.setIconImage(image);
//f.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/ctx.PNG")));

How to resolve path of a static file in Java?

How can I find path of a xml (static myXml.xml) file that is embedded into jar? Obviously not by absolute path but I am facing same kind of problem with relative paths. I cannot get it relative to home folder as Java returns different home folder depending upon from where I am calling the accessing Java class. For instance, from:
command prompt
App server
Eclipse launcher
Eclipse remote debugger etc
Is there someway that my accessing class (packed in same jar) may access embedded xml regardless of where jar file exists and who is trying to access it?
What you need to do is use the class loader to load the file:
InputStream stream = this.getClass().getClassLoader().
getResourceAsStream("myXml.xml");
The above code assumes that the file is at the top level of your jar.
Have you tried the getResource and getResourceAsStream methods in the Class class? Usually those are what I have to resort to in these situations.
Hope this helps.
You can use ClassLoader#getResource(..) to get InputStream of a file from the classpath:
Object.class.getClassLoader().getResource().openStream()
Also there are some other methods in ClassLoader which could be useful in your case.

Categories

Resources