MPh-py / MPh

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

Connect failure with Comsol 6.1 on Linux #114

Closed maederan201 closed 1 year ago

maederan201 commented 1 year ago

Hi John,

I updated to COMSOL 6.1 and have troubles now getting mph to work. I installed version 1.2.1 through pip on a Linux machine. When I do (in a python3.11.0 IPython console)

import mph
mph.start(cores=1)

I get the following error:

Traceback (most recent call last):
  File "java.lang.Thread.java", line -1, in java.lang.Thread.run
java.lang.java.lang.NoClassDefFoundError: java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.jetty.http.HttpParser

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

Traceback (most recent call last):
  File "java.lang.Thread.java", line -1, in java.lang.Thread.run
org.eclipse.jetty.websocket.api.org.eclipse.jetty.websocket.api.UpgradeException: org.eclipse.jetty.websocket.api.UpgradeException: 0 null

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

Traceback (most recent call last):
  File "SourceFile", line 249, in com.comsol.model.util.ModelUtil.connect
java.io.java.io.IOException: java.io.IOException: Connect failure

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

Traceback (most recent call last):
  File "SourceFile", line 249, in com.comsol.model.util.ModelUtil.connect
Exception: Java Exception

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

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/maederan/Documents/00 Repositories/MPh/mph/session.py", line 104, in start
    client = Client(cores=cores, version=version, port=server.port)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maederan/Documents/00 Repositories/MPh/mph/client.py", line 241, in __init__
    self.connect(port, host)
  File "/home/maederan/Documents/00 Repositories/MPh/mph/client.py", line 421, in connect
    self.java.connect(host, port)
com.comsol.util.exceptions.com.comsol.util.exceptions.FlException: Exception:
        java.io.IOException: Connect failure
        (rethrown as com.comsol.util.exceptions.FlException)
Messages:
        Failed to connect to server

        Connect failure

When I do

import mph
mph.Client(cores=1)

I get a different error:

Traceback (most recent call last):
  File "SourceFile", line 411, in com.comsol.model.util.ModelUtil.initStandalone
Exception: Java Exception

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

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/maederan/Documents/00 Repositories/MPh/mph/client.py", line 199, in __init__
    java.initStandalone(False)
java.lang.java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: /usr/local/comsol61/multiphysics/lib/glnxa64/libcssystemutil.so: libiomp5.so: cannot open shared object file: No such file or directory

Lastly, if I do

import mph
mph.Server(cores=1, port=12345)
mph.Client(cores=1, port=12345)

I get the same error as if I do mph.start(...) from the 3rd line mph.Clinet(...). So maybe the error is fundamentally related to libiomp5.so is the problem, however libiomp5.so is present in multiple places, which are

/opt/lumerical/v212/lib/libiomp5.so
/opt/lumerical/v212/python-3.6.8rc1/lib/python3.6/site-packages/scipy/.libs/lib/libiomp5.so
/opt/lumerical/v221/lib/libiomp5.so
/opt/lumerical/v221/python-3.6.8rc1/lib/python3.6/site-packages/scipy/.libs/lib/libiomp5.so
/usr/local/Wolfram/Mathematica/12.3/SystemFiles/Libraries/Linux-x86-64/libiomp5.so
/usr/local/comsol61/multiphysics/ext/cadimport/glnxa64/acis/code/bin/libiomp5.so
/usr/local/comsol61/multiphysics/lib/glnxa64/libiomp5.so
maederan201 commented 1 year ago

It might also be related to (or a duplicate of) #100 .

john-hen commented 1 year ago

Hi Andreas, thanks for reporting this. I cannot reproduce this on our cluster, which is running CentOS 7. Which Linux distro are you on?

I don't think the two issues are related. This here seems to be a problem with some Java library (Jetty), whereas the other is about an external native library (Intel Math Library). At first glance, this looks like an issue with Comsol itself, not something I could fix. But we'd have to reproduce it with Java code only to be sure. I'll look into that. The scenario is simple enough: just the client/server start-up.

(Your second attempt does not work because that's trying to start a stand-alone client, which doesn't work out of the box on Linux, see "Platform differences". So this part is expected.)

maederan201 commented 1 year ago

I'm running KDE neon 5.26. Thanks for looking into it. I'm not very familiar with Java so I probably cannot help much with reproducing it with java only :(

john-hen commented 1 year ago

I can reproduce the error on Ubuntu 22.04 LTS. That's essentially the same distro as KDE neon 5.26. I can also produce the error with Java code alone. So it's not a problem on the Python side. The error only occurs with Comsol 6.1, but not with 6.0. So something's amiss with the new Comsol version, I would think.

This is the minimal Java example, connect.java:

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

public class connect {
    public static void main(String[] args) {
        ModelUtil.connect("localhost", 2036);
        System.out.println("Success.");
        ModelUtil.disconnect();
        System.exit(0);
    }
}

Start a Comsol 6.0 server instance, in a separate terminal:

$ /usr/local/comsol60/multiphysics/bin/comsol mphserver

If we compile and run the above Java class with Comsol 6.0, it works as expected:

$ ComsolDir=/usr/local/comsol60/multiphysics
$ $ComsolDir/bin/comsol compile connect.java
$ $ComsolDir/java/glnxa64/jre/bin/java -classpath ".:$ComsolDir/plugins/*" connect
Success.

But with Comsol 6.1 (and a Comsol 6.1 server started separately):

$ ComsolDir=/usr/local/comsol61/multiphysics
$ $ComsolDir/bin/comsol compile connect.java
$ $ComsolDir/java/glnxa64/jre/bin/java -classpath ".:$ComsolDir/plugins/*" connect
Exception in thread "main" Exception:
    java.io.IOException: Connect failure
    (rethrown as com.comsol.util.exceptions.FlException)
Messages:
    Failed to connect to server

    Connect failure

Stack trace:
at org.eclipse.jetty.websocket.jsr356.ClientContainer.connect(ClientContainer.java:263)
    at org.eclipse.jetty.websocket.jsr356.ClientContainer.connectToServer(ClientContainer.java:293)
    at com.comsol.client.interfaces.ClientWebSocketCommandManager.a(SourceFile:228)
    at com.comsol.clientapi.engine.APIEngine$c.a(SourceFile:556)
    at com.comsol.clientapi.engine.APIEngine$c.a(SourceFile:1)
    at com.comsol.clientapi.engine.APIEngine$a.a(SourceFile:488)
    at com.comsol.clientapi.engine.APIEngine.a(SourceFile:157)
    at com.comsol.clientapi.engine.APIEngine.connect(SourceFile:143)
    at com.comsol.clientapi.engine.APIEngine.connect(SourceFile:132)
    at com.comsol.clientapi.engine.MphServerConnection.connect(SourceFile:68)
    at com.comsol.clientapi.engine.MphServerConnection.connect(SourceFile:55)
    at com.comsol.model.util.ModelUtil.connect(SourceFile:249)
    at connect.main(connect.class:7)
Caused by: org.eclipse.jetty.websocket.api.UpgradeException: 0 null
    at org.eclipse.jetty.websocket.client.WebSocketUpgradeRequest.onComplete(WebSocketUpgradeRequest.java:529)
    at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:218)
    at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:210)
    at org.eclipse.jetty.client.HttpExchange.notifyFailureComplete(HttpExchange.java:269)
    at org.eclipse.jetty.client.HttpExchange.abort(HttpExchange.java:240)
    at org.eclipse.jetty.client.HttpConversation.abort(HttpConversation.java:149)
    at org.eclipse.jetty.client.HttpRequest.abort(HttpRequest.java:812)
    at org.eclipse.jetty.client.HttpDestination.abort(HttpDestination.java:507)
    at org.eclipse.jetty.client.HttpDestination.failed(HttpDestination.java:253)
    at org.eclipse.jetty.client.AbstractConnectionPool$1.failed(AbstractConnectionPool.java:270)
    at org.eclipse.jetty.util.Promise$Wrapper.failed(Promise.java:136)
    at org.eclipse.jetty.client.HttpClient$1$1.failed(HttpClient.java:627)
    at org.eclipse.jetty.client.AbstractConnectorHttpClientTransport.connectFailed(AbstractConnectorHttpClientTransport.java:138)
    at org.eclipse.jetty.client.AbstractConnectorHttpClientTransport$ClientSelectorManager.connectionFailed(AbstractConnectorHttpClientTransport.java:188)
    at org.eclipse.jetty.io.ManagedSelector$Connect.failed(ManagedSelector.java:966)
    at org.eclipse.jetty.io.ManagedSelector$CreateEndPoint.run(ManagedSelector.java:1077)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:773)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:905)
    at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoSuchMethodError: 'org.eclipse.jetty.util.Trie org.eclipse.jetty.util.Trie.empty(boolean)'
    at org.eclipse.jetty.http.HttpParser.<clinit>(HttpParser.java:106)
    at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.<init>(HttpReceiverOverHTTP.java:55)
    at org.eclipse.jetty.client.http.HttpChannelOverHTTP.newHttpReceiver(HttpChannelOverHTTP.java:60)
    at org.eclipse.jetty.client.http.HttpChannelOverHTTP.<init>(HttpChannelOverHTTP.java:50)
    at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.newHttpChannel(HttpConnectionOverHTTP.java:67)
    at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.<init>(HttpConnectionOverHTTP.java:62)
    at org.eclipse.jetty.client.http.HttpClientTransportOverHTTP.newHttpConnection(HttpClientTransportOverHTTP.java:71)
    at org.eclipse.jetty.client.http.HttpClientTransportOverHTTP.newConnection(HttpClientTransportOverHTTP.java:63)
    at org.eclipse.jetty.client.AbstractConnectorHttpClientTransport$ClientSelectorManager.newConnection(AbstractConnectorHttpClientTransport.java:180)
    at org.eclipse.jetty.io.ManagedSelector.createEndPoint(ManagedSelector.java:386)
    at org.eclipse.jetty.io.ManagedSelector.access$2100(ManagedSelector.java:65)
    at org.eclipse.jetty.io.ManagedSelector$CreateEndPoint.run(ManagedSelector.java:1069)
    ... 3 more/

The cause is again the UpgradeException in the Eclipse Jetty library. Due to that, the client cannot connect to the server. What is strange is that this exception only occurs on some Linux distros, but not all, even though the Java libraries at work here are necessarily the same. In fact, they should be the same across platforms even. I don't see anything I can do here at this point. Unless, maybe, this has something to do with (Java) security policies or firewall rules or something on certain systems. But more likely than not, this is something only Comsol can fix.

maederan201 commented 1 year ago

Hi John,

Thanks for looking into it. I guess this would be something to take up with COMSOL Support? I can do it later Today, maybe there is a workaround.

For now, I'll probably have to stick to COMSOL 6.0

maederan201 commented 1 year ago

Hi John,

COMSOL Support may have figured out the problem.

Apparently changing the -classpath to apiplugins works, so if I change the third command to

$ $ComsolDir/java/glnxa64/jre/bin/java -classpath ".:$ComsolDir/apiplugins/*" connect

Your connect.java example works.

I'll have a look if I can figure it out myself how this helps... Update on that soon.

john-hen commented 1 year ago

That is awesome news, thanks for following up on this! :pray:

I don't quite understand why, but if the tests pass, then I'll gladly take it. Will run the test suite on other platforms I can get access to just to make sure.

For the record, the Comsol documentation never mentions the apiplugins folder. It only ever says to "add all JAR files placed in the plugins directory". I've always wondered what apiplugins is for then, so that's a bit mysterious.