MPh-py / MPh

Pythonic scripting interface for Comsol Multiphysics
https://mph.readthedocs.io
MIT License
249 stars 66 forks source link

`UnsatisfiedLinkError` when loading model #57

Open shehan807 opened 2 years ago

shehan807 commented 2 years ago

Hi,

I'm creating a new issue as per #56--the following code results in the subsequent errors:

client = mph.start(cores=1)
model = client.load('my_file.mph')
  File "SourceFile", line 168, in com.comsol.model.util.ModelUtil.load
  File "SourceFile", line 134, in com.comsol.model.util.ServerModelUtil.load
  File "SourceFile", line 930, in com.comsol.model.util.ServerModelUtil.a
  File "SourceFile", line 636, in com.comsol.nativeutil.d.b.m
  File "SourceFile", line 22, in com.comsol.nativeutil.d.c.<clinit>
  File "SourceFile", line 166, in com.comsol.nativejni.util.FlLicense.getInstance
  File "SourceFile", line 71, in com.comsol.nativejni.util.FlLicense.<init>
  File "SourceFile", line -2, in com.comsol.nativejni.util.FlLicense.initWS0
Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File ".\runAcc.py", line 8, in <module>
    model = client.load('PEPPER-Sweep_CMNT_ACC_only.mph')
  File "C:\Users\PSPL_Workstation_1\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-package
s\Python38\site-packages\mph\client.py", line 324, in load
    model = Model(self.java.load(tag, str(file)))
java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: 
com.comsol.nativejni.util.FlLicense.initWS0(Lcom/comsol/nativejni/CPointer;)V

I've referenced the edge case from #49, and the following lines do not result in any errors (when I run from a Windows machine using Powershell):

import jpype
jpype.startJVM('C:/Program Files/COMSOL/COMSOL56/Multiphysics/java/win64/jre/bin/server/jvm.dll')

I've also looked into the test suite and am able to run just about all the test_ scripts except for test_model.py, test_node.py, and test_standalone.py. Pasted below are the errors from test_model.py and test_standalone.py, respectively.

  File "SourceFile", line 90, in com.comsol.model.util.ModelUtil.createUnique
  File "SourceFile", line 83, in com.comsol.model.util.ModelUtil.create
  File "SourceFile", line 42, in com.comsol.model.util.ServerModelUtil.create
  File "SourceFile", line 636, in com.comsol.nativeutil.d.b.m
  File "SourceFile", line 22, in com.comsol.nativeutil.d.c.<clinit>
  File "SourceFile", line 166, in com.comsol.nativejni.util.FlLicense.getInstance
  File "SourceFile", line 71, in com.comsol.nativejni.util.FlLicense.<init>
  File "SourceFile", line -2, in com.comsol.nativejni.util.FlLicense.initWS0
Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File ".\test_model.py", line 694, in <module>
    setup_module()
  File ".\test_model.py", line 28, in setup_module
    model  = models.capacitor()
  File "C:\Users\PSPL_Workstation_1\SP\comsol\MPh-main\tests\models.py", line 10, in capacitor
    model = mph.session.client.create('capacitor')
  File "C:\Users\PSPL_Workstation_1\SP\comsol\MPh-main\mph\client.py", line 356, in create
    java = self.java.createUnique('model')
java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: 
com.comsol.nativejni.util.FlLicense.initWS0(Lcom/comsol/nativejni/CPointer;)V
  File "SourceFile", line 90, in com.comsol.model.util.ModelUtil.createUnique
  File "SourceFile", line 83, in com.comsol.model.util.ModelUtil.create
  File "SourceFile", line 42, in com.comsol.model.util.ServerModelUtil.create
  File "SourceFile", line 636, in com.comsol.nativeutil.d.b.m
  File "SourceFile", line 22, in com.comsol.nativeutil.d.c.<clinit>
  File "SourceFile", line 166, in com.comsol.nativejni.util.FlLicense.getInstance
  File "SourceFile", line 71, in com.comsol.nativejni.util.FlLicense.<init>
  File "SourceFile", line -2, in com.comsol.nativejni.util.FlLicense.initWS0
Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File ".\test_standalone.py", line 57, in <module>
    test_start()
  File ".\test_standalone.py", line 26, in test_start
    model = client.create('empty')
  File "C:\Users\PSPL_Workstation_1\SP\comsol\MPh-main\mph\client.py", line 356, in create
    java = self.java.createUnique('model')
java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: 
com.comsol.nativejni.util.FlLicense.initWS0(Lcom/comsol/nativejni/CPointer;)V

As was mentioned earlier, this is using an FNL license, though it is unlikely to be the source of the error. There seems to be an issue with the createUnique function but I am not too sure why it wouldn't work. Your assistance would be greatly appreciated.

john-hen commented 2 years ago

Great, you already ran the test suite. This helps because we can see that even test_standalone.py fails, which is a test script that does very little. So that narrows it down quite a bit.

It does essentially this:

import mph

client = mph.start()
model = client.create('empty')
model.save()

That just creates an empty model and saves it. Running the above script (let's call it empty.py) would put a file named empty.mph in the script's folder, which we could then open in the Comsol GUI and it would contain, well, nothing, apart from a few default nodes. And that works as described when I run it. For you, it should produce the same error as before. Please confirm this before going any further.

Now, we can do the same thing in Java. You don't need to install anything, Comsol alone will do. We're just following the Comsol Programming Manual here, specifically the "Getting Started" section (page 20), although I will make it even simpler by doing the equivalent of the above Python script.

Create this empty.java file:

import com.comsol.model.*;
import com.comsol.model.util.*;

public class empty {
    public static void main(String[] args) throws java.io.IOException {
        ModelUtil.initStandalone(false);
        Model model = ModelUtil.create("empty");
        model.save("empty.mph");
        System.exit(0);
    }
}

Then compile it using this command on the Windows command prompt:

"C:\Program Files\COMSOL\COMSOL56\Multiphysics\bin\win64\comsolcompile.exe" empty.java

Adjust the path for your Comsol installation if it's a different version or you installed it in a custom location. This should create a file named empty.class in the same directory. We can run it like so:

"C:\Program Files\COMSOL\COMSOL56\Multiphysics\java\win64\jre\bin\java.exe" -classpath ".;C:\Program Files\COMSOL\COMSOL56\Multiphysics\plugins\*" empty

This should create the afore-mentioned empty.mph model file.

If it doesn't, then only Comsol can help you. And they should. This (using the Java API) is an officially supported use case.

If it does work in Java, but not in Python, then, well, the only clue I got while writing this is that I get pretty much exactly the same error as you do if I comment out the line ModelUtil.initStandalone(false); in the Java file. It would not explain why you get that error in Python, because that's one (among a few other things) that mph.start() already does. But we could take it from there then.

shehan807 commented 2 years ago

Thanks for your quick response! The empty.py does in fact result in the same error as before. I am able to successfully create the empty.mph model file using the empty.java that you provided.

john-hen commented 2 years ago

Hm, then it seems like the stand-alone client does not get initialized. I have no idea why though. Can you run the test_standalone script again, but with log messages turned on? Like so:

$ python tests\test_standalone.py log debug
Starting local Comsol session.
Checking registry node "SOFTWARE\Comsol\COMSOL56".
Checking installation folder "C:\Program Files\COMSOL\COMSOL56\Multiphysics".
Reported version info is "COMSOL Multiphysics 5.6.0.280".
Assigned name "5.6" to this installation.
JPype version is 1.3.0.
Starting Java virtual machine.
JVM arguments: ['C:\\Program Files\\COMSOL\\COMSOL56\\Multiphysics\\java\\win64\\jre\\bin\\server\\jvm.dll']
Java virtual machine has started.
Initializing stand-alone client.
Stand-alone client initialized.
Created model "empty" with tag "model1".
Retagging "components/Component 1": "tag1" → "comp1".
Removing model "empty" with tag "model1".
Exiting the Java virtual machine.

Assuming you're in the project root folder, I think it's named MPh-main in your case. I removed the time-stamps, they don't matter. The interesting line is "Stand-alone client initialized."

You can also try running in client-server mode, i.e. not with the stand-alone client. This is the default on Linux, but you're on Windows. So you would need to explicitly activate this option, like so:

import mph

mph.option('session', 'client-server')
client = mph.start()
model = client.create('empty')
model.save()
shehan807 commented 2 years ago

Here are the log messages from test_standalone, it seems like the error occurs right after the stand-alone client is initialized:

Checking registry node "SOFTWARE\Comsol\COMSOL56".
Checking installation folder "C:\Program Files\COMSOL\COMSOL56\Multiphysics".
Reported version info is "COMSOL Multiphysics 5.6.0.401".
Assigned name "5.6" to this installation.
JPype version is 1.3.0.
Starting Java virtual machine.
JVM arguments: ['C:\\Program Files\\COMSOL\\COMSOL56\\Multiphysics\\java\\win64\\jre\\bin\\server\\jvm.dll']
Java virtual machine has started.
Initializing stand-alone client.
Stand-alone client initialized.
Traceback (most recent call last):
  File "SourceFile", line 90, in com.comsol.model.util.ModelUtil.createUnique
  File "SourceFile", line 83, in com.comsol.model.util.ModelUtil.create
  File "SourceFile", line 42, in com.comsol.model.util.ServerModelUtil.create
  File "SourceFile", line 636, in com.comsol.nativeutil.d.b.m
  File "SourceFile", line 22, in com.comsol.nativeutil.d.c.<clinit>
  File "SourceFile", line 166, in com.comsol.nativejni.util.FlLicense.getInstance
  File "SourceFile", line 71, in com.comsol.nativejni.util.FlLicense.<init>
  File "SourceFile", line -2, in com.comsol.nativejni.util.FlLicense.initWS0
Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File ".\tests\test_standalone.py", line 57, in <module>
    test_start()
  File ".\tests\test_standalone.py", line 26, in test_start
    model = client.create('empty')
  File "C:\Users\PSPL_Workstation_1\SP\comsol\MPh-main\mph\client.py", line 356, in create
    java = self.java.createUnique('model')
java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: 
com.comsol.nativejni.util.FlLicense.initWS0(Lcom/comsol/nativejni/CPointer;)V
Exiting the Java virtual machine.

Adding mph.option('session', 'client-server') now works for the empty.mph example and the original example. If I understand correctly, running on the stand-alone mode is the most reliable on Windows but the simulations will not be negatively affected if on client-server mode (aside from the caveats you mentioned in the documentation), correct?

john-hen commented 2 years ago

Yes, stand-alone mode would be better. But client-server mode will work as well. Some things will be a bit slower, but not the simulations themselves. And you'll occasionally get the InterruptedException described in #38. Which is harmless, but a bit annoying. Basically a slightly worse user experience, though in the end it's the same as on Linux and macOS. (You can make that option permanent so you don't have to include it in the code every time, see the config module.)

It frustrates me a bit that I have no explanation for the behavior you report. That doesn't bode well for MPh in terms of reliability. But I'm out of ideas at this point, so not much else to do about it.

For the record, the following script does the same as empty.py, but doesn't use MPh. All calls are made directly to the Comsol Java API via JPype. And the paths are simply hard-coded.

import jpype
import jpype.imports

root = 'C:/Program Files/COMSOL/COMSOL56/Multiphysics'
jvm  = root + '/java/win64/jre/bin/server/jvm.dll'
jars = root + '/plugins/*'
jpype.startJVM(jvm, classpath=jars)

from com.comsol.model.util import ModelUtil
ModelUtil.initStandalone(False)

model = ModelUtil.createUnique('empty')
model.save('empty.mph')

jpype.java.lang.Runtime.getRuntime().exit(0)

Based on the error messages you got with other scripts, this one will also fail when the line containing createUnique is hit. But that's the end of the road then: That's just Comsol being called through JPype. Also for the record, none of Comsol's folders are on my search PATH, so Comsol gets no extra help with finding its DLLs. (Come to think of it, it may also be counter-productive if an older Comsol installation was on the search path. One last thing you could check.)

So, sorry about that. If you discover something that might shed some light on this issue, please report back. We'll have to leave it open anyway as it's unresolved. Using client-server mode, I'd consider that a work-around. Though obviously it's also not that big a deal.

Armin268 commented 1 year ago

By running this line: model = client.load('capacitor.mph') I get this error: Traceback (most recent call last): File "SourceFile", line 169, in com.comsol.model.util.ModelUtil.load Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last): File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2544.0_x64__qbz5n2kfra8p0\lib\idlelib\run.py", line 578, in runcode exec(code, self.locals) File "C:\Users\armin\Documents\PFC-CFD\PFC_COMSOL\MPh-Test\MPh-main\tests\capacitor.py", line 3, in model = client.load('capacitor.mph') File "C:\Users\armin\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\mph\client.py", line 322, in load model = Model(self.java.load(tag, str(file))) java.lang.java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: 'void com.comsol.nativejni.util.FlLicense.initWS0(com.comsol.nativejni.CPointer, java.lang.String)'

What should I do?

Thank You

YohanAymonBFH commented 1 year ago

Hello,

I'm facing the same issue. Still no update on how to fix it ?

I'm on a floating license that might lead to other problems...

Thanks

john-hen commented 1 year ago

No update, no. I cannot reproduce the error, so can't fix it. And using client-server mode seems to fix it anyway.

john-hen commented 9 months ago

Just this week, in an entirely unrelated context (nothing to do with Comsol), I ran into a strange conflict with external libraries, which would only occur when the user had Python installed from the Microsoft Store. On Windows, obviously. I just realized that the two previous error reports, further up in the thread, also used the Microsoft Store version of Python.

On that hunch — and it's a mere hunch —, I would recommend that users, who run into the issue discussed here, uninstall Python and reinstall it using the official Python installer from python.org.

Obviously, I have no idea if that actually fixes the issue. (I cannot reproduce it, after all.) But if you had this issue and using the official python.org installer fixed it, please report back here. Likewise, if you have this issue with the python.org Python installation, kindly let people know as well.

garretlanglois commented 1 month ago

This is an old issue however I ran into the same issue as the users above and following from the above comment I manually installed the python version and that fixed the problem for me. Just for future reference for anyone else that has this problem.

john-hen commented 1 month ago

@garretlanglois Thanks for the feedback! I'll add this to the documentation before the next release (whenever that may be), as it's pretty solid evidence that there's something that breaks MPh in the Microsoft Store version of Python. (Probably got something to do with different external libraries being linked against.)