Forum Discussion

FICO's avatar
FICO
Community Manager
3 years ago

new XPRM() initialization error in multi-threaded Java programs

Hi, I wrote a multi-threaded Java program to run a large number of small MIP problems. Occasionally, the XPRM() initialization fails at this line:

XPRM xprm = new XPRM();

When I print the error stack trace, it starts like this:

java.lang.RuntimeException: default streams cannot be set: is 'mmjava' properly installed?

at com.dashoptimization.XPRM.<init>(Unknown Source)

at com.dashoptimization.XPRM.<init>(Unknown Source)

I thought the multi-thread may be the cause, so I wrote a new class implementing Lock interface, so that at any time, only 1 thread could call new XPRM();

final class XPRMLock{

private final Lock lock = new ReentrantLock();

public XPRM XPRMinit() {

lock.lock();

XPRM xprm=null;

try {

xprm = new XPRM();

}catch (Exception e) {

e.printStackTrace();

} finally {

if (lock != null) {

lock.unlock();

}

}

return xprm;

}

}

However, I still occasionally see error, fails at new XPRM();

My question is, what is this error? and what should I do to make sure it's safe to run in multi-threaded environment. Or is that because in a short period of time, too many XPRM() are initialized so it runs out of memory internally? (the MIP problems I am solving are tiny, take only a few milliseconds to solve each).

Thanks!

Jie

8 Replies

  • FICO's avatar
    FICO
    Community Manager

    Hi Jie,

    which operating system are you using and which version of Xpress? Do you suspect that your application could run out of memory? Did you check the overall memory usage of your system during the execution of your application. Is your application running in docker or a virtual machine?

    Would it be possible that you share the full Java and Mosel source code of your app (and data) or a minimal version of it that reproduces the problem? I assume that you are using mmjava to share data between Java and Mosel. I'm in particular interested in the code that you use to communicate between Java and Mosel, since this could be a potential source for a memory corruption. You could send it to [email protected] or share it here.

    Regards, Johannes

  • FICO's avatar
    FICO
    Community Manager

    Hi, Johannes, I use Windows 11 Home, and Xpress 8.14. The java program I wrote is a Microservice using spring framework (Spring | Home). Clients send REST API calls, and the server side accepts the calls and process the data (running a MIP model for each all). I checked overall memory usage and JVM heap; it didn't show any issue at all. If I slow down the client calls a little bit, there is no problem (new XPRM() won't run into any error). It's when I do a load testing, let client side send huge number of calls constantly at high speed (every few milliseconds), then the new XPRM() run into errors.

    I didn't use mmjava in my program and didn't what it is (before today). If you want the code (which has many lines), I will have to reorganize it to remove the irrelevant lines and only focus on the ones that is relevant to this issue.

    Thanks,

    Jie

  • FICO's avatar
    FICO
    Community Manager

    Hi Jie,

    Is it be possible for you to upgrade to the latest Xpress version: 9.0.0 ?

    Could you try to run your application on Linux (e.g. in a VM or Docker) or on Mac, to see if the problem reproduces on a different OS?

    Which version of Java are you using and from which vendor (Amazon, ...)?

    This sounds like a race condition and could also be a memory corruption that is caused by a race condition. Since there are problems with the initialization of the standard output streams, this could also be an issue related to Windows. It would be interesting to see whether the problem exclusively happens on Windows or whether it also reproduces on Linux or macOS. In the past, I have observed problems with initialization of the standard output streams on Windows when we tried to load the Python library into the Mosel process. At that point in time, Mosel and Python were using different versions of the Microsoft C compiler, and Windows basically didn't support applications that loaded libraries into the same process that had been compiled with those two different versions of the C compiler; and the error message we got was that the standard output stream couldn't be initializes sometimes (e.g. in one of 100 cases). However, those kind of issues should be very rare. I'm just mentioning it for the sake of completeness, and to give you an understanding why I think that it could help to know whether this problem only occurs on Windows, or whether it also reproduces on Linux or Mac.

    If it's a race condition that is caused by an issue in Xpress or Mosel, then it would be helpful if you could share at least the source of the Mosel model, the code that calls the Mosel model, and an example input for the model. Race conditions are hard to reproduce, and if we have to try to reproduce it on our side, without having much source code from your side, it might be difficult to reproduce the problem on our side. However, if it's not possible for you to provide more code, I can just write a stress test for XPRM init and see whether that's enough to reproduce the issue.

    Regards,

    Johannes

  • FICO's avatar
    FICO
    Community Manager

    Hi Jie,

    we can now reproduce it on our side. I will forward the issue to the maintainers of the Mosel Java API and they will look at it as soon as possible.

    In the meantime, could you please try to create a single xprm instance for your entire process, instead of creating a new instance for each thread or model? Does that resolve your issue?

    Regards, Johannes

  • FICO's avatar
    FICO
    Community Manager

    Hi, Johannes,

    I just tried on version 9.0.0 and the problem is still there. I was just about to try on Linux and saw your message. Good to hear you can now reproduce it on your side. I will let you guys investigate from now on. If possible, please give me an update when the issue is fixed.

    I will try to create a single xprm instance for the entire process and see if that works in the multi-thread parallel processing environment.

    Thanks! and Happy holidays!

    Jie

  • FICO's avatar
    FICO
    Community Manager

    Hi Jie,

    it can take quite a while until a fix is available in an official patch release (especially due to the holidays), so please go ahead and try to use a single xprm instance for the entire multi-processed application. Unfortunately, the documentation isn't very precise about whether this is supported or not, so I also asked the maintainers to improve the doc. I had a quick look at the source of XPRM and tested a single xprm instance in my multi-threaded toy application and it worked as expected and solved the issue that you observed. So I think this should also solve it on your side.

    Let me know if this doesn't solve the issue for you!

    Regards,

    Johannes

  • FICO's avatar
    FICO
    Community Manager

    Hi, Johannes, I just tried using a single xprm instance in my app, and it seems working fine! This is great! Thanks so much for your help!!!

    Best,

    Jie