When using java from Matlab, is there some way to figure out from where in matlab's java class path is a class being loaded? I'm trying to diagnose a error caused by conflicting versions of the same class being used simultaneously.
Specifically, the class I'm looking for is org.apache.lucene.store.FSDirectory. It seems to be used by one of the matlab toolboxes, but I don't know which one.
From http://www.exampledepot.com/egs/java.lang/ClassOrigin.html
// Get the location of this class
Class cls = this.getClass();
ProtectionDomain pDomain = cls.getProtectionDomain();
CodeSource cSource = pDomain.getCodeSource();
URL loc = cSource.getLocation(); // file:/c:/almanac14/examples/
Assuming that an URLClassLoader is being used, you can get the file: URL of the class file like this:
ProblemClass.class.getResource("ProblemClass.class")
Per Thorbjørn Ravn Andersen, if j reference to a java object in Matlab, its location can be retrieved with the following line of matlab code:
j.getClass().getProtectionDomain().getCodeSource().getLocation().getPath()
Use the inmem function as follows:
[M,X,J] = inmem
This function returns the list of Java classes in the output argument J. (It also returns the names of all currently loaded M-files in M, and the names of all currently loaded MEX-files in X.)
Here's a sample of output from the inmem function:
[m,x,j] = inmem;
MATLAB displays:
j =
'java.util.Date'
'com.mathworks.ide.desktop.MLDesktop'
Since 1.5 using:
java -verbose:class
Prints where each class was loaded from.
Related
In this question, I was trying to import java classes into Octave. In my particular example, I was (and am) working with javaplex, a set of java tools with code for implementation in Matlab. The answer to the question shows that, whereas in Matlab you would do the following:
import edu.stanford.math.plex4.*;
api.Plex4.createExplicitSimplexStream();
The answer provided in the question showed that the way to do this in Octave is
javaMethod( 'createExplicitSimplexStream', 'edu.stanford.math.plex4.api.Plex4')
This was working excellently, but then I ran into a strange problem. There is another method called createVietorisRipsStream. In Matlab, I would run this with a line such as the following:
api.Plex4.createVietorisRipsStream(parameters);
So I would think that the equivalent command in Octave would be
javaMethod( 'createVietorisRipsStream', 'edu.stanford.math.plex4.api.Plex4')
However, when I do this, I get the following error:
error: [java] java.lang.NoSuchMethodException: createVietorisRipsStream
I'm not sure why this error is coming up, and both are in the same JAVA file ('Plex4'). I did take a look at the Plex4 file, and there are two differences between createExplicitSimplexStream and createVietorisRipsStream that I noticed:
There are two instances of createExplicitSimplexStream and six instances of createVietorisRipsStream
There is bit that says <double[]>. I don't know if that is relevant however (I haven't read or wrote much java, up to this point, I've been able to use the tutorial they provided to only use Matlab and not have to look under the hood).
Here is one example of the code from the Plex4 file for a createExplicitSimplexStream:
public static ExplicitSimplexStream createExplicitSimplexStream(double maxFiltrationValue) {
return new ExplicitSimplexStream(maxFiltrationValue);
}
Here is one example of the code from the Plex4 file for a createVietorisRipsStream:
public static VietorisRipsStream<double[]> createVietorisRipsStream(double[][] points, int maxDimension, double maxFiltrationValue, int numDivisions) {
return FilteredStreamInterface.createPlex4VietorisRipsStream(points, maxDimension, maxFiltrationValue, numDivisions);
}
Any idea of why I'm getting the error I'm getting?
Read the octave documentation for the Java section properly, it's only 4 pages, and it explains this well!
As I mentioned in the comments in the previous question, the way to call a java method with arguments is:
javamethod(
name of method as a string,
name of class fully qualified with packages as a string,
method's first argument,
method's second argument,
... etc
)
This is the only way to call 'static' methods; with normal 'instance' methods, you can either use javaMethod and replace the name of the class by the java object itself, or simply use it as you would in java, i.e. objectname.methodname(arg1, arg2, ... etc)
I have implemented here the tutorial for you to have a look at (page 14 in the pdf). (don't forget to run the modified 'load_javaplex' script first).
octave:2> max_dimension = 3;
octave:3> max_filtration_value = 4;
octave:4> num_divisions = 1000;
octave:5> point_cloud = javaMethod( 'getHouseExample', 'edu.stanford.math.plex4.examples.PointCloudExamples')
point_cloud =
<Java object: double[][]>
octave:6> stream = javaMethod( 'createVietorisRipsStream', 'edu.stanford.math.plex4.api.Plex4', point_cloud, max_dimension, max_filtration_value, num_divisions)
stream =
<Java object: edu.stanford.math.plex4.streams.impl.VietorisRipsStream>
octave:7> persistence = javaMethod( 'getModularSimplicialAlgorithm', 'edu.stanford.math.plex4.api.Plex4', max_dimension, 2)
persistence =
<Java object: edu.stanford.math.plex4.autogen.homology.IntAbsoluteHomology>
octave:8> intervals = persistence.computeIntervals(stream)
intervals =
<Java object: edu.stanford.math.plex4.homology.barcodes.BarcodeCollection>
(I have not gone further because plot_barcodes needs to be modified a bit too; it's only a couple of lines but it would be too much to post here, the reasoning is the same though).
Also, if you're not sure what is meant by class constructors, class methods, and static vs instance-specific methods, unfortunately this is more to do with java, although it should be pretty introductory stuff. It is well worth reading up a bit about it first.
Good luck!
I have a java class I am using in my jruby project and in ruby I can set a value to an object via the send method. I am doing the same in jruby but using the java_send method instead. However, when I try using this I get the following error TypeError: can't convert Java::JavaIo::File into Array from org/jruby/java/proxies/JavaProxy.java:321:in 'java_send'
I have a java instance and I need to call the object via a symbol. Below is what I am doing in the code:
OUTPUT_FILES = [:make, :model]
javaArgs = javaArgs.new
OUTPUT_FILES.each do |filename|
file = java.io.File.new(path, "#{filename.to_s.underscore}.csv")
file.createNewFile
javaArgs.java_send(filename, file)
end
and just to make sure when I do javaArgs.make = file it works without any problems.
java_send expects its arguments passed as an array: javaArgs.java_send filename, [ file ]
I have a simple python script in my local machine, which returns a string. I want to run this script from java application and get the return value. I'm trying to do this using Pyrolite. I downloaded the jar files and added them to my java class path. But I'm not able to run the script.
I got the below sample code from readme.txt
NameServerProxy ns = NameServerProxy.locateNS(null);
PyroProxy remoteobject = new PyroProxy(ns.lookup("Your.Pyro.Object"));
Object result = remoteobject.call("pythonmethod", 42, "hello", new int[]{1,2,3});
String message = (String)result; // cast to the type that 'pythonmethod' returns
System.out.println("result message="+message);
remoteobject.close();
ns.close();
But this is not working for me. My system configuration is
OS: Windows 8
JDK: jdk1.7.0_51
Python: 2.6
Please help me with this.
This is how I have edited the code:
NameServerProxy ns = NameServerProxy.locateNS(null);
PyroProxy remoteobject = new PyroProxy();
Object result = remoteobject.call("C:\\trail1.py", null);
String message = (String)result; // cast to the type that 'pythonmethod' returns
System.out.println("result message="+message);
remoteobject.close();
ns.close();
I'm not positive that I understand what you're trying to do.
If you carefully read the tutorial, you'll see that you can't use Pyrolite the way you are. It specifies that you must have a python script running as a server, WITH a name server, where you must define some classes (for example Your.Pyro.Object).
Then you'll be able to call those objects you defined in that python script, but not the script itself.
To do what you want to do you'll need to call a function like C's fork(). Then you're able to call an executable, and you don't need Pyrolite.
I've been struggling with this problem for two days now and no resource I've found have been able to solve it.
I am trying to call a java class (added the link at the bottom) from Matlab (version 7.13.0.564 (R2011b)). I've compiled the java class using java 1.6 into a .class file and also added the path to the folder where the file is situated using javaaddpath (I've of course checked that the path is correct in the list of dynamic paths). However, when I try to call the class from Matlab using javaMethod('main','PerlinNoiseGenerator','') I get the error:
"No class PerlinNoiseGenerator can be located on Java class path"
I would be extremely grateful if someone with experience in calling java from Matlab could put together a short tut on how to do this. I am probably going to distribute my code so I kinda need to set the java path dynamically and from what I've read it really should be possible although I've seen post that indicate that it could be the cause of the problem.
http://svn.j3d.org/code/tags/Xj3D-M10/src/java/org/j3d/texture/procedural/PerlinNoiseGenerator.java
Usually I create jar files that contain java classes. I also had problems loading individual java classes before. In your case I did the following on xubuntu 13.04 x64 and Matlab 2013a x64 to load your particular class:
Compile it using java 6 (not the default 7) with option -d . to create a set of package folders, as your class defines a package org/j3d/texture/proecedural/ etc:
/usr/lib/jvm/java-6-openjdk-amd64/bin/javac -d . PerlinNoiseGenerator.java
This will compile the class and make in the current director (thus .) the set of package folders.
Make jar file containing your class again using jar from java 6. I named it javaNoise.jar:
/usr/lib/jvm/java-6-openjdk-amd64/bin/jar cf javaNoise.jar ./org/j3d/texture/procedural/PerlinNoiseGenerator.class
In Matlab, in the directory where javaNoise.jar is:
javaaddpath('./javaNoise.jar');
Create object of your java class:
png=org.j3d.texture.procedural.PerlinNoiseGenerator()
% results in: png = org.j3d.texture.procedural.PerlinNoiseGenerator#3982a033
To test it, I just generated some 1D noise:
png.noise1(1.2)
ans = -0.0960
Hope this helps.
P.S.
javaMethod('main','PerlinNoiseGenerator','') wont work because this class has no main method:-).
Your notation to the compiler of the constructor is a polymorphic class meaning "use appropriate constructor that is called at runtime".
public PerlinNoiseGenerator()
public PerlinNoiseGenerator(int seed)
The first form with no argument can be called but is irrelevent because the line with this(DEFAULT_SEED) attempts to call itself but only one constructor is allowed used
Second constructor has int for an argument but requires being loaded by an already loaded class.
Use the first version and change the case sensitive name of the one with the argument and remove this(DEFAULT_SEED) from it replace with the method name(the one you changed from a constructor that has the argument).
e.g. public perlinNoiseGenerator(int seed)
note: by convention java code method names start with a lower-case letter.
A final note, java arguments from the command line come in as "String" data type through the "main" method, a starter method for applications (gui or command prompt).
The first argument on the main method argument is the first commandline argument.
public static void main(String[] Args){
new PerlinNoiseGenerator(Args); // recursive class call
}//end main method
int[] args; // global
public PerlinNoiseGenerator(String[] Args){
int arglength=Args.length();
args = new int[arglength];
for(int cnt=0;cnt<arglength;cnt++){
Args[cnt].trim();
args[cnt]=new Integer(Args[cnt]).intValue();
}//enfor
perlinNoiseGenerator(args[0]); // call method
}//end constructor
I created my own new R library (called "Media"). There is no problem when I try to load it with RGui, and I can call the functions defined in the new package. This is how I load it:
> library(Media)
But, I'm also trying to call that functions from Java/JRI code, and when I load the new R package, Java doesn't seem to find the pacakge, throwing the message "Error in library(Media) : object 'Media' not found"
This is my current code using JRI:
REXP rexpSetFolder = re.eval("setwd('C:/Users/Albert/Documents')");
REXP rexpFolder = re.eval("getwd()");
System.out.println(rexpFolder.asString());
REXP rexpLoad = re.eval("library(Media)"); // fails
It also fails without the 'setwd' command, and simple calls to existing R functions work fine. I'm using R 2.10 and the latest JRI 0.5-0 under Windows.
Any help would be appreciated.
Thank you very much.
Edit:
The parameter lib.loc seems to work, at least this sentence does not return an error:
library("Media", lib.loc = "c:/Users/Albert/Documents")
But after that, calling a function in the package with re.eval("myfunction()"); still fails, as the function is not properly found.
You can modify the library path - see ?.libPaths in R, you simply want to add your private library to the path. The GUI does that for you, but if you are outside it doesn't happen. For example:
re.eval(".libPaths('c:/users/foo/Documents/R')");
Then load your package.
Did you install the library properly first? You might want to try using the lib.loc parameter.
library("Media", lib.loc = "c:/Users/Albert/Documents")
My work-around was to copy the package from my personal library (%USERPROFILE%\Documents\R) to the global library (%R_HOME%\library).
It's not the best because this requires Administrator privileges which not all users will have...