Is it possible to make MatlabEngine class object persistent in Java?

3 visualizaciones (últimos 30 días)
Yuriy Alexandrov
Yuriy Alexandrov el 26 de En. de 2021
Respondida: Amish el 14 de Mayo de 2024
Dear Matlab specialists!
My colleague wrote a simple Java class (code below) to create and use MatlabEngine "eng" object in the run() function. It works normally.
However, when one makes this object a member of class and then tries to reuse it, it looks like the whole associated Matlab session disappears after the first usage.
I am intersted in creating MatlabEngine object/session "eng" in a way when it is possible to call it from other Java classes for which the Java class where it is created, is visible. In particular, I'd like to create a Matlab class object within "eng", make some setups (which need quite long calculations), and then call the "Do(current_data)" function of this created Matlab class on my current data, i.e. whenever/wherever needed in Java. For that obviously, this "eng" object and its session should be persistent. So my question is - is it posibble at all?
Best wishes,
Y.
import com.mathworks.engine.EngineException;
import com.mathworks.engine.MatlabEngine;
import com.mathworks.engine.MatlabSyntaxException;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class javaFevalFcnMulti implements Runnable{
String[] args;
int num1;
int num2;
public javaFevalFcnMulti(String[] args_in, int num1_in, int num2_in){
args = args_in;
num1 = num1_in;
num2 = num2_in;
}
@Override
public void run() {
MatlabEngine eng;
try {
System.out.println("MLT started");
eng = MatlabEngine.startMatlab();
Object[] results = eng.feval(3, "gcd", num1, num2);
Integer G = (Integer)results[0];
Integer U = (Integer)results[1];
Integer V = (Integer)results[2];
eng.close();
System.out.println("Greatest common divisor of "+Integer.toString(num1)+" and "+Integer.toString(num2)+" is "+G.toString());
} catch (EngineException ex) {
Logger.getLogger(javaFevalFcnMulti.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(javaFevalFcnMulti.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(javaFevalFcnMulti.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalStateException ex) {
Logger.getLogger(javaFevalFcnMulti.class.getName()).log(Level.SEVERE, null, ex);
} catch (MatlabSyntaxException ex) {
Logger.getLogger(javaFevalFcnMulti.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(javaFevalFcnMulti.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Respuestas (1)

Amish
Amish el 14 de Mayo de 2024
Hi Yuriy,
I understand that you want to create a persistent "MatlabEngine" object that can be reused across different parts of a Java application, including from different classes.
Given the code you've shared, it appears that the MatlabEngine eng is being created and closed within the "run()" method of your "javaFevalFcnMulti" class. Therefore it so happens that each time an instance of "javaFevalFcnMulti" is run, a new MatlabEngine session is started and then closed, which is why you're not able to reuse the MatlabEngine session across different parts of your application.
In order for you ti have a persistent and a reusable MatlabEngine session, you will need to manage the lifecycle of the object correctly. This should be done by using the "Singleton" pattern with this class. This will ensure that only one instance of the MatlabEngine is created and used throughout your application, which will help in keeping the session persistent.
Additionally, you will also need to follow the rules of Initialization on demand and proper shutdown to make sure of proper resource utilization.
Here is a general way you can implement the singleton pattern in Java:
public class MatlabEngineManager {
private static MatlabEngineManager instance;
private MatlabEngine eng;
private MatlabEngineManager() {
try {
eng = MatlabEngine.startMatlab();
} catch (Exception e) {
e.printStackTrace();
}
}
public static synchronized MatlabEngineManager getInstance() {
if (instance == null) {
instance = new MatlabEngineManager();
}
return instance;
}
public MatlabEngine getEngine() {
return eng;
}
public void shutdown() {
try {
if (eng != null) {
eng.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
You can add further implementations and functionalities over this. Additionally, you can refer to the following resources:
Hope this helps!

Categorías

Más información sobre Call MATLAB from Java en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by