|
| 1 | +# GraalPy Troubleshooting |
| 2 | + |
| 3 | +[[TOC]] |
| 4 | + |
| 5 | +## GraalPy Embedding |
| 6 | + |
| 7 | +#### VirtualFileSystem cannot load a file |
| 8 | +There are situations where a file cannot be loaded even though it is part of the Virtual Filesystem resources. |
| 9 | +GraalPy tries to prevent such situations by automatically [extracting](Embedding-Build-Tools.md#extracting-files-from-virtual-filesystem) |
| 10 | +some well known files to the real filesystem, but if you see an error like: |
| 11 | +``` |
| 12 | +ImportError: cannot load /graalpy_vfs/venv/lib/python3.11/site-packages/_cffi_backend.graalpy250dev09433ef706-311-native-aarch64-darwin.so: |
| 13 | +NFIUnsatisfiedLinkError: dlopen(/graalpy_vfs/venv/lib/python3.11/site-packages/_cffi_backend.graalpy250dev09433ef706-311-native-aarch64-darwin.so, 0x0002): |
| 14 | +``` |
| 15 | +then the default behavior did not work as intended. |
| 16 | + |
| 17 | +Depending on how you [deploy Python resources](Embedding-Build-Tools.md#deployment) in your application, you can try one of the following: |
| 18 | +- if you need to package resources within your Jar or Native Image executable: |
| 19 | + - if the problematic file is not one of the following types: `.so`, `.dylib`, `.pyd`, `.dll`, or `.ttf`, which are extracted to |
| 20 | + the real filesystem by default, you can simply attempt to add it to the extraction filter using: |
| 21 | + ```java |
| 22 | + VirtualFileSystem.Builder.extractFilter(filter); |
| 23 | + ``` |
| 24 | + - if the previous does not help, it is also possible to extract all Python resources into a user-defined directory before creating a GraalPy |
| 25 | + context, and then configure the context to use that directory: |
| 26 | + ```java |
| 27 | + // extract the Python resources from the jar or native image into a given directory |
| 28 | + GraalPyResources.extractVirtualFileSystemResources(VirtualFileSystem.create(), externalResourceDirectoryPath); |
| 29 | + // create a GraalPy context configured with an external Python resource directory |
| 30 | + Context context = GraalPyResources.contextBuilder(externalResourceDirectoryPath).build(); |
| 31 | + ``` |
| 32 | +- or if you're able to ship resources in a separate directory, you have to set the `externalDirectory` tag in |
| 33 | + [Maven](Embedding-Build-Tools.md#graalpy-maven-plugin) or `externalDirectory` field in [Gradle](Embedding-Build-Tools.md#graalpy-gradle-plugin) |
| 34 | + and also configure the GraalPy context to use that directory as well: |
| 35 | + ```java |
| 36 | + // create a Context configured with an external Python resource directory |
| 37 | + Context context = GraalPyResources.contextBuilder(externalResourceDirectoryPath).build(); |
| 38 | + ``` |
| 39 | + Please **note**, that if switching from Virtual FileSystem to an external directory, also all **user files** from the previous |
| 40 | + Virtual FileSystem resource root have to be moved into that directory as well. |
| 41 | + |
| 42 | +For more details about the Python resources in GraalPy Embedding please refer to the [Embedding Build Tools](Embedding-Build-Tools.md) documentation. |
| 43 | + |
| 44 | +For more details about GraalPy context and Virtual FileSystem configuration please refer to [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java) and |
| 45 | +[VirtualFileSystem](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/VirtualFileSystem.java) javadoc. |
| 46 | + |
| 47 | +#### Issues with GraalPy 'java' posix backend |
| 48 | +The Virtual FileSystem is built on the Truffle filesystem and relies on the GraalPy Java POSIX backend. |
| 49 | +Unfortunately, certain Python packages bypass Python's I/O and directly access files through their |
| 50 | +native extensions. If you encounter an error like: |
| 51 | +``` |
| 52 | +NotImplementedError: 'PyObject_AsFileDescriptor' not supported when using 'java' posix backend |
| 53 | +``` |
| 54 | +then you have to override the default `java` GraalPy backend option byt setting the `native` POSIX backend |
| 55 | +and completely omit the Virtual FileSystem at runtime. |
| 56 | + |
| 57 | +Depending on how you [deploy Python resources](Embedding-Build-Tools.md#deployment) in your application, |
| 58 | +you can do one of the following: |
| 59 | + |
| 60 | +- if you need to package Python resources within your Jar or Native Image executable, then: |
| 61 | + ```java |
| 62 | + // extract the Python resources from the jar or native image into a given directory |
| 63 | + GraalPyResources.extractVirtualFileSystemResources(VirtualFileSystem.create(), externalResourceDirectoryPath); |
| 64 | + // create a Context.Builder configured with an external python resource directory |
| 65 | + Builder builder = GraalPyResources.contextBuilder(externalResourceDirectoryPath); |
| 66 | + // override the python.PosixModuleBackend option with "native" |
| 67 | + builder.option("python.PosixModuleBackend", "native"); |
| 68 | + // create a context |
| 69 | + Context context = builder.build(); |
| 70 | + ``` |
| 71 | +- or if you're able to ship Python resources in a separate directory, you have to set the `externalDirectory` tag in |
| 72 | + [Maven](Embedding-Build-Tools.md#graalpy-maven-plugin) or `externalDirectory` field in [Gradle](Embedding-Build-Tools.md#graalpy-gradle-plugin) |
| 73 | + and configure the GraalPy context accordingly: |
| 74 | + ```java |
| 75 | + // create a Context.Builder configured with an external python resource directory |
| 76 | + Builder builder = GraalPyResources.contextBuilder(externalResourceDirectoryPath); |
| 77 | + // override the python.PosixModuleBackend option with "native" |
| 78 | + builder.option("python.PosixModuleBackend", "native"); |
| 79 | + // create a context |
| 80 | + Context context = builder.build(); |
| 81 | + ``` |
| 82 | + Please **note**, that if switching from Virtual FileSystem to an external directory, also all **user files** from the previous |
| 83 | + Virtual FileSystem resource root have to be moved into that directory as well. |
| 84 | + |
| 85 | +For more details about the Python resources in GraalPy Embedding please refer to the [Embedding Build Tools](Embedding-Build-Tools.md) documentation. |
| 86 | + |
| 87 | +For more details about GraalPy context and Virtual FileSystem configuration please refer to [GraalPyResources](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java) and |
| 88 | +[VirtualFileSystem](https://github.com/oracle/graalpython/blob/master/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/VirtualFileSystem.java) javadoc. |
| 89 | + |
| 90 | +### Maven and Gradle applications |
| 91 | + |
| 92 | +#### ImportError reports "unknown location" |
| 93 | +A possible cause of an `ImportError` ending with `(unknown location)` when running a GraalPy Java Embedding project might be |
| 94 | +that an embedded Python package was built for a different operating system. If you see an error like the following: |
| 95 | +``` |
| 96 | +ImportError: cannot import name 'exceptions' from 'cryptography.hazmat.bindings._rust' (unknown location) |
| 97 | +``` |
| 98 | +You probably need to rebuild your project on the correct operating system before running it. |
| 99 | + |
| 100 | +#### GraalVM JDK Compatibility |
| 101 | +To enable runtime compilation when running GraalPy from a Maven or Gradle application, |
| 102 | +you must use versions of GraalPy and the Polyglot API dependencies that are compatible |
| 103 | +with the specified GraalVM JDK version. If you see errors like the following: |
| 104 | + |
| 105 | +``` |
| 106 | +Your Java runtime '23.0.1+11-jvmci-b01' with compiler version '24.1.1' is incompatible with polyglot version '24.1.0'. |
| 107 | +``` |
| 108 | +You need to keep the versions of your GraalPy and Polyglot dependencies according to the error message, |
| 109 | +so either upgrade the version of your JDK or your polyglot and GraalPy dependencies. |
| 110 | + |
| 111 | +Note, this can also apply to cases when your dependencies are transitively pulled in by another artifact, |
| 112 | +e.g. micronaut-graalpy. |
| 113 | + |
| 114 | +#### The following artifacts could not be resolved: org.graalvm.python:python-language-enterprise |
| 115 | +`python-language-enterprise` was discontinued, use `org.graalvm.polyglot:python` instead. |
| 116 | + |
| 117 | +#### Issues with Meson build system when installing Python packages on OSX with Maven or Gradle GraalPy plugin |
| 118 | +Errors like the following: |
| 119 | +``` |
| 120 | +../meson.build:1:0: ERROR: Failed running 'cython', binary or interpreter not executable. |
| 121 | +``` |
| 122 | + |
| 123 | +could be caused by the GraalPy launcher used internally by the Maven or Gradle GraalPy plugin |
| 124 | +for installing Python packages. Currently, there is no straightforward solution. However, |
| 125 | +a workaround is to set the Java system property graalpy.vfs.venvLauncher to a launcher from |
| 126 | +a downloaded [GraalPy](https://github.com/oracle/graalpython/releases/) distribution with a version |
| 127 | +matching the GraalPy Maven artifacts version. |
| 128 | + |
| 129 | +e.g. |
| 130 | +``` |
| 131 | +mvn package -Dgraalpy.vfs.venvLauncher={graalpy_directroy}/Contents/Home/bin/graalpy |
| 132 | +``` |
| 133 | + |
| 134 | +#### No language and polyglot implementation was found on the module-path. |
| 135 | +If you see an error like: |
| 136 | +``` |
| 137 | +java.lang.IllegalStateException: No language and polyglot implementation was found on the module-path. Make sure at last one language is added to the module-path. |
| 138 | +``` |
| 139 | +you are probably missing the python langauge dependency in your Maven of Gradle configuration file. |
| 140 | +You need to add either `org.graalvm.polyglot:python` or `org.graalvm.polyglot:python-community` to your dependencies. |
| 141 | + |
0 commit comments