MATLAB:How to use java code in MATLAB? - java

I want to to run java code in Matlab so I can make use of what I have learned in java to enhance my MATLAB codes.

Totally quoting from here
Suppose your Java program is like this:
public class MyClass {
public static void main( String args[] ){}
}
To call this program in MATLAB:
Outside of MATLAB: Compile this class, so you have file MyClass.class
Locate the classpath.txt file for the MATLAB installation. The location of this file can be found by typing the following command in MATLAB command window:
which classpath.txt
Open the 'classpath.txt' with a text editor as Administrator. Add the full path for the directory with the MyClass.class to the end of the 'classpath.txt' file as a single line and save the file.
Restart MATLAB.
In MATLAB: to create an object of class MyClass, type:
o = MyClass
In MATLAB: to execute main() of object o, type:
javaMethod('main', o, '')
Alternately one may also add the directory in which the class files are to the dynamic path. Use the JAVAADDPATH command to add the directory (which contains the MyClass.class file) to JAVA's dynamic classpath. This also obviates the need to restart MATLAB. Once this is done the code can be invoked as follows:
o = MyClass;
javaMethod('main', o);
For a detailed tutorial please see this.

Related

From shell, is there a Java tool to check which compiled .class file(s) have a main method?

I'm putting together some (Python) scripts to help me automate some of my grading of hundreds of simple student Java repos. Not all of them have the same directory structure or naming of files. I've traversed them all and compiled them and if I make assumptions I can run them and test them, etc. But I'd like to know if there's a way I could find the "main" .class that has the main() method in it, so that I don't have to make assumptions about their file naming (which wouldn't work all the time anyway).
I'm aware of reflection, so yes, I know I could write another simple helper Java program to assist me in identifying it myself. But I was wondering if anything already exists (java command line option, tool from the jdk, etc.) to test a .class file to see if it is has the main() method in it.
I was wondering if anything already exists (java command line option, tool from the JDK, etc.) to test a .class file to see if it is has the main() method in it.
There is no tool or option in Java SE that does that directly.
I know I could write another simple helper Java program to assist me ...
It would be simpler to write a shell script that iterates a file tree, finds .class files, calls javap on them, and greps for a method with the appropriate main method signature.
Or you could do something similar on the source code tree.
(In retrospect, you should have set the assignment requirements so that the students had to use a specified class and package name for the class containing their main method. But it is too late for that now ...)
In the C++ days, distributing the headers files to use a shared object file was a big deal. People would get one or the other without both, and there was always the chance you'd get mis-matched versions.
Java fixed that with javap which prints the methods (and other major interfaces) of a compiled .class file.
To test if a class file has a main, run
javap SomeFile.class
which will list all public interfaces. Within that list, see if it has the "main entry point"
public static void main(java.lang.String[])
Now to handle this in mass, simply create a Python script that:
Locates all the relevant classes.
Runs javap on the class.
Reads the output for a method that matches (at the beginning, as there can be a variable number of Exceptions at the end "public static void main(java.lang.String[])
And you'll find all entry points.
Keep in mind that sometimes a single library or JAR file has many entry points, some of which are not intended as the primary entry point.
Well simply calling java -cp . <file> will either completely blow out if the class doesn't have a main method or will run the relevant code. Now, if the code fails to run right and errors out you may see it as the same effect as not having a main method.
public class HasMain {
public static void main(String[] args) {
System.out.println("Hit main");
}
}
public class HasDoIt {
public static void doIt(String[] args) {
System.out.println("Hit doIt");
}
}
public class WillBlowUp {
public static void main(String[] args) {
System.out.println("Hit blowUp");
throw new IllegalStateException("oops");
}
}
Using PowerShell:
PS D:\Development\sandbox> javac HasMain.java
PS D:\Development\sandbox> javac HasDoIt.java
PS D:\Development\sandbox> javac WillBlowUp.java
PS D:\Development\sandbox> java -cp . HasMain
Hit main
PS D:\Development\sandbox> $?
True
PS D:\Development\sandbox> java -cp . HasDoIt
Error: Main method not found in class HasDoIt, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
PS D:\Development\sandbox> $?
False
PS D:\Development\sandbox> java -cp . WillBlowUp
Hit blowUp
Exception in thread "main" java.lang.IllegalStateException: oops
at WillBlowUp.main(WillBlowUp.java:4)
PS D:\Development\sandbox> $?
False
So simply checking return values could be a quick way to test if the class has what you want, albeit any exit(1) type return will throw a false-false

JNI Use native method

I'm working on a project where there's the need to call some methods from dll files.
These two dlls are
EasySign.dll
EasySignJNI
EasySignJNI depends on EasySign.
I wrote the class to load EasySignJNI as follows:
package easysign;
class EasySign {
EasySign(){}
public native String EasyHashFile(String filename);
public native int EasySign(String pkcs11_driver,String pin, int type, String file_data, int out_format, String signed_file, String cert_out, int cert_format);
public native int EasyVerify(String cert_user, String file_data, String signed_file, String crl_file, String ca_file, String out_document);
static {
System.loadLibrary("EasySignJNI");
}
}
Now I would call these method from my main method like this:
public class Test {
public static void main(String[] args) throws IOException{
EasySign es = new EasySign();
System.out.println("EasyHashFile : " + es.EasyHashFile("test.txt"));
}
}
What I have to specify in the -Djava.library.path ? Only the path where my EasySignJNI.dll is located? It is possible to call native method in this way?
I'm using NetBeans for completeness.
EDIT:
I have noticed that the third party dll provided to me (the JNI dll in particular) defines method names without any package, so I'm forced to put the class that loads the dll in the default package. Is there any way to change only the dll method names including my own package name?
EDIT 2:
What I mean is that both EasySign.dll and EasySignJNI.dll are provided me as they are and I can't modify them (I have not the source code). The EasySignJNI is the JNI portion but inspecting it I have noticed thath the method sign is in the form: _java_EasySign_MethodName. When I load the dll in Java from my Easysign class (this class must reside in the "mypackage" package), I receive the jni unsatisfiedlinkerror because, if I understood right, I'm calling the "_java_mypackage_EasySign_MethodName" method, i.e the sign is different from the dll's one. So the only way to make it work is to rewrite the JNI part and build it to have the correct sign of the JNI method?
What I have to specify in the -Djava.library.path ? Only the path where my EasySignJNI.dll is located?
Correct, the operating system will locate the dependent EasySign.dll for you as long as it is available where the OS expects it to be.
It is possible to call native method in this way? I'm using NetBeans for completeness.
I read through your edit and you have successfully lost me. What default package are you referring to? (Remember that none of us know what EasySign.dll is) So, I am going to provide some info about how I do what you originally described and hopefully it will help.
First start by compiling EasySign if you have the src. Do not build a DLL or shared object, instead build a static library. If you do not have the src code for EasySign, or a prebuilt static library, you will be stuck with the dll and can continue to the next step.
Now you are ready to compile the jni portion. All of your JNI C code should basically translate your Java input/output to their JVM/Native types and call the appropriate functions in the DLL library. You want to keep this layer and thin and simple as possible because it is incredibly difficult to debug. Your C++ package names shouldn't really matter here and you can use what ever package name you want for your Java classes. You should be able to compile the JNI code and preferably static link to the EasySign.dll file so you don't need to worry about distributing it. If you must dynamically link, make sure EasySign.dll gets installed to a location that is on the DLL PATH / LDPATH because the OS will need to locate and load that file right after the JVM loads the JNI DLL.
At this point you should just be able to point -Djava.library.path at your JNI DLL's path and all should work.

run class file as separate process from java code

public static void main(String args[]) throws IOException
{
Process p = Runtime.getRuntime().exec("java E:/workspace/JNIProgram/src/JNIProgram.class");
}
so I have this code and am trying to run the JNIProgram.class file however the program gets terminated instantly without doing its job (which is to create a new txt file and write to it)
So what am I doing wrong
The java command expects a Java class name, not a filename.
So the command java E:/workspace/JNIProgram/src/JNIProgram.class is wrong. If you try this manually from a command prompt window you'll get an error message.
The command should be something like this:
java -cp E:\workspace\JNIProgram\src JNIProgram
Note: What's after the -cp option is the classpath, and after that the fully-qualified class name (which is just JNIProgram, if the class is not in a package).
First make sure that you can run the command manually from the command line before you make it work from another Java program.

Make JAR as a standalone executable

Is there a way to convert JAR lib into JAR standalone?
I need to find a standalone java executable that convert PDF into TIFF and I've found these JARs: http://www.icefaces.org/JForum/posts/list/17504.page
Any ideas?
Easiest might be to create another Jar with a Main() entry point, and then just use the java.exe executable to run it:
e.g.
> java.exe -cp MyJarMain.jar;MyPDFJar.jar com.mydomain.MyMain myPDF.pdf
Where MyMain is a class with a Main static method.
You'll need something with a main entry point to pass in and interpret some command line arguments (myPDF.pdf in my made-up example)
You could do an assembly (are you using maven?) and make sure the Main-Class entry in the manifest.mf points to the main class.
Since there is no main-Method, you have to write one, or write a whole new class to call the class/method TiffConver.convertPDF .
The question is, how you're going to use it. From the command line, you need no executable jar. From the Gui, maybe you want to pass a file to be converted by drag and drop? Then you should take the parameter(s) passed to main as Input-PDF-Names (if they end in .pdf) and pass the names iteratively to TiffConverter, for "a.pdf b.pdf" =>
TiffConver.convertPDF ("a.pdf", "a.tiff");
TiffConver.convertPDF ("b.pdf", "b.tiff");
TiffCoverter will silently overwrite existing tiffs, so check that before or change the code there - this is clearly bad habit, and look out for more such things - I didn't.
/*
* Remove target file if exists
*/
File f = new File(tif);
if (f.exists()) {
f.delete();
}
Maybe you wan't to write a swing-wrapper, which let's you choose Files interactively to be converted. This would be a nice idee, if no filename is given.
If the user passes "a.pdf xy.tiff" you could rename the converted file to xy, as additional feature.
Without a main-class, however, a standalone jar would be magic.
However, building a native executale is almost always a bad idea. You loose portability, you don't profit from security- and performance improvements to the JVM or fixed bugs. For multiple programs you need always an independend bugfix, which you might have to manage yourself, if you don't have a package-management as most linux distros have.
after clearing some questions:
public static void main (String [] args) {
if (args.length == 1 && args[0].endsWith (".pdf")) {
String target = args[0].replaceAll (".pdf$", ".tif");
convertPDF (args[0], target);
}
}
This method you put into TiffConvert. It will allow you to convert a simple pdf-File, and generate a tif-File with the same basename but ending in .tif, silently overwriting an existing one of the same name.
I guess you now need to know how to start it?

Is it possible to "add" to classpath dynamically in java?

java -classpath ../classes;../jar;. parserTester
How can i get the functionality in the above command programmatically? Like, is it possible to run as:
java parserTester
and get the same result? I tried using URLClassLoader but it modifies the classpath and does not add to it.
Thanx!
Thanks for the response Milhous. But that is what i am trying to do.. How is it possible to get the jar into the classpath first? I tried using a custom classloader too :(
That works.. But sorry that i need to run it only as:
java parserTester
I would like to know if such a thing is possible???
It needs to be so bcoz i have parserTester.java and .class in a separate folder. I need to retain the file structure. The parserTester makes use of a jar in a separate jar folder.
You can use a java.net.URLClassLoader to load classes with any program defined list of URL's you wish:
public class URLClassLoader
extends SecureClassLoader
This class loader is used to load
classes and resources from a search
path of URLs referring to both JAR
files and directories. Any URL that
ends with a '/' is assumed to refer to
a directory. Otherwise, the URL is
assumed to refer to a JAR file which
will be opened as needed.
The AccessControlContext of the thread
that created the instance of
URLClassLoader will be used when
subsequently loading classes and
resources.
The classes that are loaded are by
default granted permission only to
access the URLs specified when the
URLClassLoader was created.
Since:
1.2
And a little fancy footwork can extend it to support using wildcarded pathnames to pick up entire directories of JARs (this code has some references to utility methods, but their implementation should be obvious in the context):
/**
* Add classPath to this loader's classpath.
* <p>
* The classpath may contain elements that include a generic file base name. A generic basename
* is a filename without the extension that may begin and/or end with an asterisk. Use of the
* asterisk denotes a partial match. Any files with an extension of ".jar" whose base name match
* the specified basename will be added to this class loaders classpath. The case of the filename is ignored.
* For example "/somedir/*abc" means all files in somedir that end with "abc.jar", "/somedir/abc*"
* means all files that start with "abc" and end with ".jar", and "/somedir/*abc*" means all files
* that contain "abc" and end with ".jar".
*
*/
public void addClassPath(String cp) {
String seps=File.pathSeparator; // separators
if(!File.pathSeparator.equals(";")) { seps+=";"; } // want to accept both system separator and ';'
for(StringTokenizer st=new StringTokenizer(cp,seps,false); st.hasMoreTokens(); ) {
String pe=st.nextToken();
File fe;
String bn=null;
if(pe.length()==0) { continue; }
fe=new File(pe);
if(fe.getName().indexOf('*')!=-1) {
bn=fe.getName();
fe=fe.getParentFile();
}
if(!fe.isAbsolute() && pe.charAt(0)!='/' && pe.charAt(0)!='\\') { fe=new File(rootPath,fe.getPath()); }
try { fe=fe.getCanonicalFile(); }
catch(IOException thr) {
log.diagln("Skipping non-existent classpath element '"+fe+"' ("+thr+").");
continue;
}
if(!GenUtil.isBlank(bn)) {
fe=new File(fe,bn);
}
if(classPathElements.contains(fe.getPath())) {
log.diagln("Skipping duplicate classpath element '"+fe+"'.");
continue;
}
else {
classPathElements.add(fe.getPath());
}
if(!GenUtil.isBlank(bn)) {
addJars(fe.getParentFile(),bn);
}
else if(!fe.exists()) { // s/never be due getCanonicalFile() above
log.diagln("Could not find classpath element '"+fe+"'");
}
else if(fe.isDirectory()) {
addURL(createUrl(fe));
}
else if(fe.getName().toLowerCase().endsWith(".zip") || fe.getName().toLowerCase().endsWith(".jar")) {
addURL(createUrl(fe));
}
else {
log.diagln("ClassPath element '"+fe+"' is not an existing directory and is not a file ending with '.zip' or '.jar'");
}
}
log.diagln("Class loader is using classpath: \""+classPath+"\".");
}
/**
* Adds a set of JAR files using a generic base name to this loader's classpath. See #link:addClassPath(String) for
* details of the generic base name.
*/
public void addJars(File dir, String nam) {
String[] jars; // matching jar files
if(nam.endsWith(".jar")) { nam=nam.substring(0,(nam.length()-4)); }
if(!dir.exists()) {
log.diagln("Could not find directory for Class Path element '"+dir+File.separator+nam+".jar'");
return;
}
if(!dir.canRead()) {
log.error("Could not read directory for Class Path element '"+dir+File.separator+nam+".jar'");
return;
}
FileSelector fs=new FileSelector(true).add("BaseName","EG",nam,true).add("Name","EW",".jar",true);
if((jars=dir.list(fs))==null) {
log.error("Error accessing directory for Class Path element '"+dir+File.separator+nam+".jar'");
}
else if(jars.length==0) {
log.diagln("No JAR files match specification '"+new File(dir,nam)+".jar'");
}
else {
log.diagln("Adding files matching specification '"+dir+File.separator+nam+".jar'");
Arrays.sort(jars,String.CASE_INSENSITIVE_ORDER);
for(int xa=0; xa<jars.length; xa++) { addURL(createUrl(new File(dir,jars[xa]))); }
}
}
private URL createUrl(File fe) {
try {
URL url=fe.toURI().toURL();
log.diagln("Added URL: '"+url.toString()+"'");
if(classPath.length()>0) { classPath+=File.pathSeparator; }
this.classPath+=fe.getPath();
return url;
}
catch(MalformedURLException thr) {
log.diagln("Classpath element '"+fe+"' could not be used to create a valid file system URL");
return null;
}
}
I have to agree with the other two posters, it sounds like you're overcomplicating a test class.
It's not that unusual to have the .java and .class files in separate folders, while depending on jar files in yet a third, without programmatically changing the classpath.
If you're doing it because you don't want to have to type the classpath on the command line everytime, I would suggest a shell script or batch file. Better yet, an IDE.
The question I really have is why are you doing trying to manage the classpath in code?
You could implement your own class loader, but that class/jar has to be in the classpath for it to be executed.
try
java -cp *.jar:. myClass
or
export CLASSPATH=./lib/tool.jar:.
java myClass
or
java -jar file.jar
You can write a batch file or shell script file to export the classpath and run the java program.
In Windows,
set classpath=%classpath%;../classes;../jars/*
java ParserTester
In Unix,
export classpath=%classpath%:../classes:../jars/*
java ParserTester
If you name the file name as parser.bat or parser.sh, you can just run that by calling parser in respective OS.
From java 1.6, you can include all the jars in a directory into the classpath just by saying /*
If you are trying to generate a java file dynamically, compile and add into the classpath, set the directory into which the class file gets generated in the classpath beforehand. It should load the class.
If you are modifying the already generated java class, basically recompiling after modification and if you want to load the new class, you need to use your custom class loader to avoid the caching of the class.
I think what you want is an "Execution Wrapper" or a platform specific "Launcher"... typically this component is used to detect your OS and architecture and dependencies and then makes adjustments before launching your application. It is an old school design pattern (talking 80's and earlier) but is still used a lot today. The idea is that you program can be system and environment agnostic and the launcher will make preparations and tell the software everything it needs to know. Many modern open source programs do this with Shell scripts and Batch Files, etc... Apache Tomcat for example. You could just as easily make the wrapper in java an have it launch the software with a command line exec (be sure to add " &" to the end of you exec command in *NIX so your wrapper can exit leaving only your software running... also lets you close the shell window without killing the process)
Did I understand right?! The only reason you have it that you want to launch your class without specifying the classpath and load it at runtime? ...
java parserTester
instead of
java -classpath ../classes;../jar;. parserTester
Probably I didn't get your reason. But if "that's" what you want you can do the following ( although it does not make much sense to me )
Launch the class
From the main method lauch another class an programatically set the classpath there.
End of history.
Something like the following "java -pseudo code "
public static void main( String [] args ) {
String classpath = "classes;../jar";
Runtime.getRuntime().execute("java + classpath + " parserTester ");
}
Please tell me if I get it right. If you want to do something else I would gladly help.
Excellent good post, in my case I did this to work well (note: Windows specific):
set classpath=%classpath%;../lib/*
java -cp %classpath% com.test.MyClass

Categories

Resources