MPh-py / MPh

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

OSError: [WinError 193] JVM DLL not found #49

Closed Miso-1 closed 3 years ago

Miso-1 commented 3 years ago

Hi,

Im trying to get a Simulation via Python in Comsol running. My issue is, that the command "mph.start()" produces the error message: "OSError: [WinError 193] JVM DLL not found"

Strange things:

  1. the jvm.dll is in the correct folder
  2. "JVM DLL not found" correspondes to [WinError 126] as far as I know. (when i move jvm.dll to another folder the error message shows: "OSError: [WinError 126] JVM DLL not found" )
  3. for [WinError 193] I can only find the message "%1 is not a valid Win32 application" in other issues: OS and all programms are 64bit, so I don't know what the problem is.

Maybe anybody knows how to fix this?

john-hen commented 3 years ago

I don't know how to fix this, and yes it is strange. To investigate, you could start by running this little script:

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

You may have to change the path if you use a different Comsol version or installed it in a custom location. Does that script produce the same error?

Miso-1 commented 3 years ago

Hi, Just tried it. Yes, it produces the same error.

john-hen commented 3 years ago

Okay, then the answer is, unfortunately, that nobody knows how to fix this. At least up until now. Though maybe you want to look into this a little more. This is a rare error that has been encountered before, but cannot be reliably reproduced by other people.

As you can see, this has nothing to do with MPh. The script above only uses JPype to try and start Comsol's Java VM, which fails. The JPype project provides some instructions for debugging JVM start-up issues on Windows. Near the very end, it has this to say:

Here are some common problems:

The architecture of the jvm or one of the dependencies does not match the program or is corrupted:

Failed to load JVM from C:\Program Files (x86)\Java\jre1.8.0_251\bin\client\jvm.dll
LastError 193
Message: %1 is not a valid Win32 application.

That's your error code right there: 193. But there is no known solution. A similar issue has been reported, jpype-project/jpype#777, also unresolved, and there the Windows error codes is 126, which, as you point out, would make a little more sense if the actual Java DLL was not found. But then again, that isn't truly the issue since it's right there and should be found. So this all points to a possible issue with the DLLs that the Java DLL itself depends on.

All I can offer here is show what the Java VM's dependencies look like on a system where everything works fine. This is Windows 10 and Comsol 5.6 is installed in its default location. None of Comsol's folders are on the search path (i.e., listed in the PATH environment variable, which on Windows is used for DLLs and executables alike).

Following JPype's debugging instructions, we need Visual Studio to get the dumpbin tool. Which I then ran on the command line to list the dependencies of jvm.dll.

$ "C:\programs\Visual Studio\VC\Auxiliary\Build\vcvars64.bat"
**********************************************************************
** Visual Studio 2019 Developer Command Prompt v16.11.3
** Copyright (c) 2021 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'

$ dumpbin /dependents "C:\Program Files\COMSOL\COMSOL56\Multiphysics\java\win64\jre\bin\server\jvm.dll"
Microsoft (R) COFF/PE Dumper Version 14.29.30133.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Dump of file C:\Program Files\COMSOL\COMSOL56\Multiphysics\java\win64\jre\bin\server\jvm.dll

File Type: DLL

  Image has the following dependencies:

    KERNEL32.dll
    USER32.dll
    ADVAPI32.dll
    WSOCK32.dll
    WINMM.dll
    VERSION.dll
    PSAPI.DLL
    MSVCR120.dll

  Summary

       76000 .data
       4C000 .pdata
      1C4000 .rdata
       2E000 .reloc
        1000 .rsrc
      5B0000 .text

All of these DLLs are in the Windows folder. For example, we can check:

$ where advapi32.dll
C:\Windows\System32\advapi32.dll

Though msvcr120.dll can also be found in Comsol's jre\bin folder, so I guess is usually loaded from there. We could make sure it's first on the search path by starting the Java VM from inside that folder.

$ cd "C:\Program Files\COMSOL\COMSOL56\Multiphysics\java\win64\jre\bin"

$ where msvcr120.dll
C:\Program Files\COMSOL\COMSOL56\Multiphysics\java\win64\jre\bin\msvcr120.dll
C:\Windows\System32\msvcr120.dll

$ python
Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import jpype
>>> jpype.startJVM('./server/jvm.dll')
>>> jpype.isJVMStarted()
True

Also according to the debug instructions, I compiled and ran testJVM.cpp from the JPype repo. (This requires that the "Windows 10 SDK" option was checked when installing Visual Studio, which it usually is though, I think.)

$ git clone https://github.com/jpype-project/jpype.git --depth 1
Cloning into 'jpype'...
remote: Enumerating objects: 557, done.
remote: Counting objects: 100% (557/557), done.
remote: Compressing objects: 100% (451/451), done.R
remote: Total 557 (delta 141), reused 218 (delta 54), pack-reused 0
Receiving objects: 100% (557/557), 809.88 KiB | 6.86 MiB/s, done.
Resolving deltas: 100% (141/141), done.

$ cd jpype\project\debug\windows

$ "C:\programs\Visual Studio\VC\Auxiliary\Build\vcvars64.bat"
**********************************************************************
** Visual Studio 2019 Developer Command Prompt v16.11.3
** Copyright (c) 2021 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'

$ cl testJVM.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30133 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

testJVM.cpp
Microsoft (R) Incremental Linker Version 14.29.30133.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:testJVM.exe
testJVM.obj

$ testJVM "C:\Program Files\COMSOL\COMSOL56\Multiphysics\java\win64\jre\bin\server\jvm.dll"
Check paths
  SystemDirectory: C:\Windows\system32
  WindowsDirectory: C:\Windows
Load library
Load entry points
  Entry point found 0000000071518010
Pack JVM arguments
  Num options: 0
Create JVM
Create Java resources
Destroy JVM
Unload library
Success

So if you see anything suspicious when you do the same on your system, that might be a clue. Otherwise, well, nobody has a solution, so you're on your own. But if you solve this, please report back, either here or even on the JPype issue I linked.

Miso-1 commented 3 years ago

Thanks for your help. I will try your suggested steps and report back if I find any solution. Nonetheless I will also inform the COMSOL-Support about this issue with JVM, maybe they know anything.

Miso-1 commented 3 years ago

I have found a way to start the JVM.

where could only find msvcr120.dll in a folder from an "Cisco Webex" installation. Starting the JVM inside the Comsol-Folder worked:

$ where msvcr120.dll
C:\Program Files (x86)\Webex\Webex\Applications\msvcr120.dll

$ cd "C:\Program Files\COMSOL\COMSOL56\Multiphysics\java\win64\jre\bin"

$ where msvcr120.dll
C:\Program Files\COMSOL\COMSOL56\Multiphysics\java\win64\jre\bin\msvcr120.dll
C:\Program Files (x86)\Webex\Webex\Applications\msvcr120.dll

$ python
Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import jpype
>>> jpype.startJVM('./server/jvm.dll')
>>> jpype.isJVMStarted()
True

Since I'm not very familiar with how to include the path of the msvcr120.dll file from the Comsol folder to be found before the one in the Webex folder and not risking crashing Webex at the same time I figuered out a workaround. Only for starting JVM I need to switch to the COMSOL folder:

import mph
import os

os.chdir(r'C:\Program Files\COMSOL\COMSOL56\Multiphysics\java\win64\jre\bin')

client=mph.start()

os.chdir(os.path.dirname(os.path.abspath(__file__)))

model=client.load('COMSOL-File.mph')
john-hen commented 3 years ago

Somehow I wasn't notified of your comment and probably marked the issue as "can't fix" a little too soon.

What happens if you just clear the PATH environment variable? Like so:

import mph
import os

os.environ['PATH'] = ''
client = mph.start()

Or if you prepend the jre\bin folder to the search path:

import mph
import os

jre = r'C:\Program Files\COMSOL\COMSOL56\Multiphysics\java\win64\jre\bin'
os.environ['PATH'] = jre + os.pathsep + os.environ['PATH']

client = mph.start()

If the latter works, then that's actually fixable in MPh library code.

john-hen commented 3 years ago

Hey, come back. @Miso-1

Miso-1 commented 3 years ago

Sorry, had a busy week.

First solution changes the error from [WinError193] to [WinError126].

If i add jre\bin to the search path as suggested in your second solution I don't get any error messages and the client is starting.

john-hen commented 3 years ago

Okay, perfect. Because that, I can fix. I just have to shuffle some things around. I'll ping you again when the new release is out, in a week or so, and then it'll (hopefully) work out of the box on your end.

To summarize (because this might help other JPype users)… What happened here is that the 64-bit Java DLL tried to import one of its dependencies, which ended up being a 32-bit DLL because of an unusual search-path order, and mixing 64-bit and 32-bit will fail. Dynamic linking is a blessing (for other reasons) and a curse (for precisely this one). If we manipulate the search path (only inside our very own Python process) prior to loading the Java VM, then it should work out.

john-hen commented 3 years ago

Should be fixed in MPh 1.1.0, released today.

@Miso-1 When you get a chance, please confirm that mph.start() now works without any search-path trickery on that computer with the Cisco Webex installation. Since I can't really test if the issue has been fixed myself.

Miso-1 commented 3 years ago

The new release fixed the problem for me. MPh is now working without any issues 👍