I am using Matlab with Java integration and am able to link Java JAR files, enabling me to both create Java objects and call methods from within Matlab. The problem is with resources. For example, if I have an XML file located in the root of the JAR I can load it successfully from within a Java app, but not from Matlab.
Does anyone have an idea on how to make Matlab access resources within JAR files?
Thanks.
If you add a jar file to MATLAB's dynamic java classpath (e.g. using javaaddpath) the resources contained in the jar will NOT be visible to any java code. As discussed in this post, items on MATLAB's dynamic classpath are not really on the classpath of the JVM. In order to access the resources in my jar file I resorted to adding the jar to the static classpath. This can be accomplished in MATLAB R2012b by creating a file named javaclasspath.txt in the directory you start MATLAB that contains a list of the jar files you are using. Relevant MATLAB documentation
The normal Java Class.getResource methods should work when called from Matlab. What syntax are you using to try to load the resource in Java and in Matlab? If using getResource, are you calling it on a Class that was loaded from the same JAR that holds the resource?
In Matlab, classes on the static and dynamic classpaths use different ClassLoaders. Resources in a JAR on the dynamic classpath may not be visible to classes on the static classpath. So if your JAR is on the dynamic classpath, you need to make sure getResource is invoked on a class that came from that same ClassLoader.
Related
I have this project that it has this structure
Home
graphics
field.txt
example.java
I need to load field.txt in my example.java in jar and I use:
getClass().getClassLoader().getResource("field.txt").toUri();
but this code it give me "Null Pointer exception" .Anyone can help me?
example.class.getResource(“/graphics/field.txt“);
The class should belong to the same jar. For Class.getResource a relative “field.txt“ is possible (same package). With ClassLoader an absolute path for all classpaths is sought: “graphics/field.txt“.
To immediately read (never write) use getResourceAsStream or the URI of the getResource. One can use a Path on the URI. Files.copy(...).
One cannot at least should not) write a resource file (as it can reside in a jar jar:file://...; and jar might even be sealed; and resources might be cached by the jvm). Keep it as read-only template. Never File.
One technique is to create an application named directory in System.getProperty("user.home") and copy the template there.
To read the file it must be in classpath, you can put the file in the folder containing .class files or add it to the classpath with java -cp option.
The issue is not so much your code, but how you build and package your jar file. You will have to clarify how you are currently building your jar (using ant, maven, eclipse, etc ?).
Many articles will also advise you to separate out your resources from your source code (.java), and many IDE will support this separation direclty by allowing you to mark a folder as a resource folder. Even maven will allow you to customize this.
See following articles:
How to package resources in Jar properly
Using maven and netbeans, it is real simple: https://coderwall.com/p/d_cvrq/how-to-package-non-java-code-files-resources-in-a-jar-with-maven, or
use maven to pack javascript files in Jar?
I have a jar file that cannot be modified, but I want to use a different .class file in place of one of the members of the jar. How can I tell Java to use the external .class file when the code within the jar attempts to load it?
You could compile another jar file with replacement classes with exactly the same name and put it ahead of the jar file in the class path. For example, this is what the various slf4j bridge jars do to replace calls to log4j or Jakarta Commons Logging in library code with cognate slf4j code; one need not maintain two sets of logging systems and configurations that way.
If you want to override a java... class, you can use some of the command line options to change the boot class path. Look at the -Xbootclasspath options in http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html. Heed the warnings.
There is also the lib/endorsed directory if you need to upgrade a third-party jar that Sun uses. Oracle uses other organizations' XML and CORBA libraries; if they release a new version and you need to adopt it, you can.
You can use AspectJ to instrument the code and possibly replace it. An around advice can call the original code if it wants.
You could see if you really need to replace the original code. Some systems provide customization hooks.
You need to make sure the external .class file is loaded first. If a class is already loaded by the class loader then it will not be reloaded. If you are using an application server, then there are ways to configure the preferences for loading classes for class loader. But if you are using a standalone application then you may need to extend the class loader to load the files in the order you want to.
I have some Jython modules that I'm trying to make work from within a JAR. Everything is set up fine except that some modules expect to open files from the filesystem that are located in the same directory as the Python script itself. This doesn't work anymore because those files are now bundled into the JAR.
Basically I want to know if there's an equivalent of Class.getResourceAsStream() that I can use from within the Python code to load these data files. I tried to use '__pyclasspath__/path/to/module/data.txt' but it didn't exist.
In java Class.getResourceAsStream() uses java's class loading system to find a resource. Python's class loading mechanism is intended to provide some similar capabilities. Most of it is described here and in PEP 302.
A quick summary of this:
when a python module is loaded, it's loader should set the __loader__ attribute
a loader should support additional methods to get data from the same source
The default zipimporter, which is used when python classes are loaded from zip or jarfiles, luckily supports this methods. So if you know a data file is located in the same jar as a python module, you could use it's loader to load it:
import some_module
data = some_module.__loader__.get_data("path/in/archive/file.txt")
Maybe I'm just missing the point, but can't you use getResourceAsStream() on a Java class?
I had the same problem, however I am not certain my circumstances were exactly the same. I did not see the exception concerning the absence of get_data until I pushed my .jar to the web and tried to WebStart it, (WebStarting locally and starting my jar with java -jar worked fine).
Anyway, this is how I solved my problem:
import SomeClass
url = SomeClass.getClassLoader().findResource('path/to/resource.txt')
inputStream = url.openStream()
# ...
SomeClass is a Java class in my .jar file. It happens to be the Java class that I use to start the Jython interpreter, so I know it will always be there.
I have an app(for CentOs) that uses two custom made shared libraries "libMyInit.so" (linked with libMyInit.so.1 and libMyInit.so.1.0.1) and libMyUtil.so (linked with libMyUtil.so.1 and libMyUtil.so libMyUtil.so.1.0.1). Thes are present inside the app packaging like MyApp/bin/libMyInit.so & MyApp/bin/util/libMyUtil.so along with their respective linked libraries.
When I have to run the app I have to explictly add the above mentioned paths to LD_LIBRARY_PATH without which it give the error like:
ERROR:Unable to load native MyUtil library. Reason: no MyUtil in java.library.path.
Is there any way I can avoid the manual adding of libraries to LD_LIBRARY_PATH ?
Something that I can do at compile time of shared libraries or later so that the custom made .so libraries are found in the java.library.path ?
IMHO the best way of doing this, is to use a custom System.loadLibrary in the static part of your classes. Have a look at my Java portaudio bindings here#github, especially at the LoadLibrary and JPA classes.
The LoadLibrary class selects a native library based on OS type and architecture, unpacks the lib from its JAR into the temp folder and loads it from there.
JPA now just has to call LoadLibrary.load and everything works automagically on all supported OSs and you only need one single JAR file.
One of the ways is to copy those libraries to one of /usr/lib, /lib, /usr/local/lib directories.
Consider a Java program, launched from a main method, that needs something from tools.jar. In this case, some utility code for connecting to JMX services. Do we have any choice but to wrap it in a shell script that uses -cp to manage the class path? We'd much rather use a MANIFEST.MF classpath.
from http://java.sun.com/developer/Books/javaprogramming/JAR/basics/manifest.html
the URLs in the Class-Path header are given relative to the URL of the JAR file of the applet or application.
I do not believe you have a choice about using a shell wrapper to get the tools.jar on your classpath. unless you write some custom classloader internally to allow you to find external jars.
If incorporating classes from the dependency jar is an option, I'd go with creation of a "Runnable JAR file". Basically you extract the classes from it and put them with your own classes in the JAR. That eliminates the need for a wrapping script.
To do that in Eclipse, select your project, File -> Export -> Java -> Runnable JAR file; that option will require that you have executed the main class at least once to know what profile to run when you actually run produced JAR.