How to run a MATLAB file (.m file) from java? - java

I am trying to figure out a way to run a .m file from java.
When the .m file is run it outputs a text file that I need to retrieve. I already have the code to retrieve the text file in java but I still cannot figure out how to start and run the .m file from java so that it outputs the file that I need. Any ideas?

You can just start a Java process and run matlab..."matlab -r "yourMfile"

Here is the code, you are looking for:
import matlabcontrol.*;
public class matlabconnect
{
public static void main(String[] args)
throws MatlabConnectionException, MatlabInvocationException
{
// create proxy
MatlabProxyFactoryOptions options =
new MatlabProxyFactoryOptions.Builder()
.setUsePreviouslyControlledSession(true)
.build();
MatlabProxyFactory factory = new MatlabProxyFactory(options);
MatlabProxy proxy = factory.getProxy();
// call builtin function
proxy.eval("disp('hello world')");
// call user-defined function (must be on the path)
proxy.feval("matlab_file_name");
// close connection
proxy.disconnect();
}
I have tested the program. It is working well. Do not forget to put your matlab file to its default path.

There is already a bit newer api for matlab / JAVA
<dependency>
<groupId>com.diffplug.matsim</groupId>
<artifactId>matconsolectl</artifactId>
<version>4.5.0</version>
</dependency>
and
// create proxy
MatlabProxyFactoryOptions.Builder builder = new MatlabProxyFactoryOptions.Builder();
MatlabProxyFactory factory = new MatlabProxyFactory(builder.build());
// get the proxy
MatlabProxy proxy = factory.getProxy();
// call user-defined function (must be on the path)
proxy.eval("addpath('"...PATH..."')");
proxy.feval("function");
// close connection
proxy.disconnect();

I think MatlabControl is what you want. It's all described here: http://www.cs.virginia.edu/~whitehouse/matlab/JavaMatlab.html
In essence, call
MatlabControl.eval("yourfile.m");

Related

Running a Python program in Java using Jython

I wrote a Python program that consists out of five .py script files.
I want to execute the main of those python scripts from within a Java Application.
What are my options to do so? Using the PythonInterpreter doesn't work, as for example the datetime module can't be loaded from Jython (and I don't want the user to determine his Python path for those dependencies to work).
I compiled the whole folder to .class files using Jython's compileall. Can I embed these .class files somehow to execute the main file from within my Java Application, or how should I proceed?
Have a look at the ProcessBuilder class in java: https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html.
The command used in the java constructor should be the same as what you would type in a command line. For example:
Process p = new ProcessBuilder("python", "myScript.py", "firstargument").start();
(the process builder does the same thing as the python subprocess module).
Have a look at running scripts through processbuilder
N.B. as for the Jython part of the question, if you go to the jython website (have a look at the FAQ section of their website www.jython.org). Check the entry "use jython from java".
I'm also interested in running Python code directly within Java, using Jython, and avoiding the need for an installed Python interpreter.
The article, 'Embedding Jython in Java Applications' explains how to reference an external *.py Python script, and pass it argument parameters, no installed Python interpreter necessary:
#pymodule.py - make this file accessible to your Java code
def square(value):
return value*value
This function can then be executed either by creating a string that
executes it, or by retrieving a pointer to the function and calling
its call method with the correct parameters:
//Java code implementing Jython and calling pymodule.py
import org.python.util.PythonInterpreter;
import org.python.core.*;
public class ImportExample {
public static void main(String [] args) throws PyException
{
PythonInterpreter pi = new PythonInterpreter();
pi.exec("from pymodule import square");
pi.set("integer", new PyInteger(42));
pi.exec("result = square(integer)");
pi.exec("print(result)");
PyInteger result = (PyInteger)pi.get("result");
System.out.println("result: "+ result.asInt());
PyFunction pf = (PyFunction)pi.get("square");
System.out.println(pf.__call__(new PyInteger(5)));
}
}
Jython's Maven/Gradle/etc dependency strings can be found at http://mvnrepository.com/artifact/org.python/jython-standalone/2.7.1
Jython JavaDoc
It is possible to load the other modules. You just need to specify the python path where your custom modules can be found. See the following test case and I am using the Python datatime/math modules inside my calling function (my_maths()) and I have multiple python files in the python.path which are imported by the main.py
#Test
public void testJython() {
Properties properties = System.getProperties();
properties.put("python.path", ".\\src\\test\\resources");
PythonInterpreter.initialize(System.getProperties(), properties, new String[0]);
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.execfile(".\\src\\test\\resources\\main.py");
interpreter.set("id", 150); //set variable value
interpreter.exec("val = my_maths(id)"); //the calling function in main.py
Integer returnVal = (Integer) interpreter.eval("val").__tojava__(Integer.class);
System.out.println("return from python: " + returnVal);
}

Using Expect for Groovy to automate an interactive CLI session

I'm using this code:
http://groovy.codehaus.org/Expect+for+Groovy
to attempt to automate a python based CLI.
My test main function is below.
Running this however, it seems that it never actually reads data from the process.
If I change the process to /bin/ls and expect some filename, it will work correctly, which leads me to believe it cant handle the fact that python is waiting for input, while /bin/ls closes the stream and flushes it.
Any ideas? Thanks.
public static void test2(String[] args){
println "Main"
def builder = new ProcessBuilder("/usr/bin/python");
builder.redirectErrorStream()
builder.redirectOutput(ProcessBuilder.Redirect.PIPE);
builder.redirectInput(ProcessBuilder.Redirect.PIPE);
def expectSession = new IOSession(builder.start());
expectSession.expect(">>>");
expectSession.send("print(%d) % (1+1)")
expectSession.expect("2");
expectSession.send("quit()");
expectSession.close();
println "Done...";
}
Looking through the source for IOSession it looks like this might be a bug in the constructor. Try:
def expectSession = new IOSession();
expectSession.addProcess(builder.start());
Also, you have to add \r to the end of the strings you are sending.

Using command line Interface app as library

I want to create a GUI app in java for signing j2me app which is done by JadTool.jar but it is a Command Line Interface Apps. So I just want to use it as library and pass the parameters in program. How it can be done?
Check out Runtime. It will allow you to execute a command. You can use this to start your command line interface library.
Edit:
Ah, I didn't read care carefully earlier. If you're using a Java library starting a separate process is not the best solution.
Just reference the JadTool jar from your project. If the functionality you need isn't accessible in the library, edit the source and recompile. Make sure JadTool's license allows this.
If you're against editing the source (or not allowed) try using reflection to invoke the private run method you need.
A jar is just a library of classes, the fact that it can be run from the command line is caused by the presence of a main method in a class. As jadtool's source is available it's easy to see its very simple main:
public static void main(String[] args) {
int exitStatus = -1;
try {
new JadTool().run(args);
exitStatus = 0;
} catch (Exception e) {
System.err.println("\n" + e.getMessage() + "\n");
}
System.exit(exitStatus);
}
Unfortunately, that run() method is private, so calling it directly from another class won't work, leading to a reduced set of options:
#WilliamMorrison 's solution of going via Runtime - not really a library call, but it would work.
see Any way to Invoke a private method?

Use java library from python (Python wrapper for java library)

I have a java library in jar form which can be used to extract data from files(excel,xml etc). As its in java, it can be used only in java applications. But i need the same library to be used for python projects as well.
I have tried py4j etc which takes the objects from jvm. But the library is not an executable and wont be 'run'. I have checked Jython but i need the library to be accessible from Python projects.
I have thought about using automated java to python translators, but i would take that as the last resort.
Please suggest some way i can accomplish this.
You can make a one class java program with a thread never ending until you send from Python a notification to do so.
This way the lib would be kept in memory and accessible from your Python program.
This class could be like this (add your needed lib import/init) :
public class TestPy {
private Thread thread;
public void die() {
synchronized (thread) {
thread.interrupt();
}
}
public TestPy() {
thread = new Thread(){
public void run() {
try {
while (!Thread.interrupted()) {
Thread.sleep(500);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
};
thread.start();
}
public static void main(String[] args) {
TestPy tp = new TestPy();
GatewayServer server = new GatewayServer(tp);
server.start();
}
}
You would have to launch the java program, use the lib, and then use the die() method to kill the java program in Python :
gateway = JavaGateway()
do your stuff here using the lib
tp = gateway.entry_point
tp.die()
You can write a simple command line Java program which calls the library and saves the results in a format you can read in Python, then you can call the program from Python using os.system.
Another option is to find Python libraries with equivalent functionality to the Java library: you can read excel, xml and other files in Python, that's not a problem.
I haven't learned how to create new instances of java class in a jar file by java constructors, but accidentally found that it's very easy to use any java static methods to access java objects in py2j.
step 1: download py4j zip file from https://pypi.python.org/pypi/py4j. "py4j0.10.0.jar" is in the zip file.
step 2: install py4j by
pip install 'D:\Downloads\py4j-0.10.0.zip'
step 3: add py4j0.10.0.jar as well as the_lib_you_use.jar (like owlapi-distribution-3.5.0.jar for the example below) to build path in your eclipse project
step 4: create AdditionApplication.java, and copy and paste the code of AdditionApplication.java at https://www.py4j.org/, and run Java application AdditionApplication.java
step 5: after running AdditoinApplication.java, test the example code in a python file:
if __name__ == '__main__':
pass
from py4j.java_gateway import JavaGateway
gateway = JavaGateway() # connect to the JVM
random = gateway.jvm.java.util.Random() # create a java.util.Random instance
number1 = random.nextInt(10) # call the Random.nextInt method
number2 = random.nextInt(10)
print(number1,number2)
(2, 7)
addition_app = gateway.entry_point # get the AdditionApplication instance
addition_app.addition(number1,number2) # call the addition method
Math = gateway.jvm.java.lang.Math
a = Math.max(4, 6);
print a
IRI = gateway.jvm.org.semanticweb.owlapi.model.IRI
abcIRI = IRI.create('fewf#fe')
print 'abcIRi = ' + str(abcIRI)
print 'abcIRI.getFragment() = ' + abcIRI.getFragment()
The result on console is :
(5, 0)
6
abcIRi = fewf#fe
abcIRI.getFragment() = fe

How can I easily write a REPL app in Java?

I have a CMS server that provides a client library. I'd like to be able to drive the CMS interactively from the command line.
The basic approach would be:
Create a connection to the CMS
Add the CMS connection object to the REPL context
Connect the REPL to stdout/stderr/stdin
Kick off a daemon thread for to keep the REPL running.
I was hoping that I could perhaps leverage Groovy to do this but haven't managed to get it working.
Is there a library that provides REPL support?
Can you provide a simple example?
If you don't mind using Scala as your language, you can use the Scala REPL to explore java libraries. You can do this in a number of ways, either with
$ scala -classpath yourjarfileshere.jar
or if you're using maven:
mvn scala:console
If all you're doing is playing (not scripting or anything), then this is a possible way to go.
If you wish to embed your repl, and you're still willing to use Scala, you can look at the answer to these questions: Drop into interpreter during arbitrary scala code location
and Launch Scala REPL programatically?
Groovy also has a repl, groovysh, which you can use to explore.
I got this working with Groovy.
Example
public static void main(final String[] args) {
Binding binding = new Binding();
// Configure your bindings here.
Groovysh shell = new Groovysh(binding, new IO());
shell.run(args);
}
Known Issues
However, it won't work when the app is started from Eclipse (ie using the Eclipse 'console' view). To work around this you must update the Eclipse launch configuration to pass the following VM argument:
-Djline.terminal=jline.UnsupportedTerminal.
More information
Documentation of the Groovy Shell.
Wikipedia page for REPL mentions BeanShell. Would that work?
Beanshell can be run as repl in your own thread/main within your application:
public static void main(String[] args) throws Exception{
Reader inreader = new InputStreamReader(System.in);
Interpreter i = new Interpreter(inreader, System.out, System.err, true);
try {
BufferedReader in = new BufferedReader(inreader);
String str;
while ((str = in.readLine()) != null) {
i.eval(str);
}
in.close();
} catch (Exception e) {
}
}
that example runs in eclipse fine, you type at it in the console window of eclipse then it will talk back to you fine.

Categories

Resources