Skip to content

Commit 6075315

Browse files
committed
Add Uber JAR documentation; Update multi-release error message.
1 parent 5401e2c commit 6075315

File tree

4 files changed

+135
-48
lines changed

4 files changed

+135
-48
lines changed

docs/reference-manual/embedding/embed-languages.md

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ In this example, `lib/polyglot` directory should contain all polyglot and langua
9393
To access polyglot classes from the class path, you must also specify the `--add-modules=org.graalvm.polyglot` JVM option.
9494
If you are using [GraalVM Native Image](#build-native-executables-from-polyglot-applications), polyglot modules on the class path will be automatically upgraded to the module path.
9595

96-
While we do support creating single uber JAR files from polyglot libraries, for example, using the Maven Assembly plugin, but we do not recommend it.
96+
While we do support [creating single uber JAR files](#uber-jar-file-creation) from polyglot libraries, for example, using the Maven Assembly plugin, we do not recommend it.
9797
Also note that uber JAR files are not supported when creating native binaries with GraalVM Native Image.
9898

9999
## Compile and Run a Polyglot Application
@@ -941,6 +941,131 @@ In this code:
941941
- The `context.eval()` call evaluates a specified snippet of guest language code.
942942
- The `listener.close()` closes a listener earlier, however execution listeners are automatically closed with the engine.
943943
944+
## Uber JAR File Creation
945+
946+
Uber JARs are JAR files that bundle all dependencies into a single archive for easier distribution.
947+
However, creating an Uber JAR is not recommended for Graal languages because it breaks module descriptors, file integrity metadata, and JAR signature information.
948+
Uber JARs are only supported on HotSpot and are not supported for native image generation, as the Native Image tool requires intact Java module descriptors.
949+
950+
If you must use Uber JARs, use the minimal configuration below and verify that it is still up to date whenever you upgrade.
951+
952+
You can find a working example of valid Maven Shade and Assembly plugin configurations in the [polyglot embedding example](https://github.com/graalvm/polyglot-embedding-demo?tab=readme-ov-file#maven-usage).
953+
See the `shade` and `assembly` profiles in [_pom.xml_](https://github.com/graalvm/polyglot-embedding-demo/blob/main/pom.xml#L384).
954+
955+
### Maven Shade Plugin
956+
957+
If you intend to use the Maven Shade plugin, include at least the following transformers and filter configuration:
958+
959+
```xml
960+
<profile>
961+
<id>shade</id>
962+
<build>
963+
<plugins>
964+
<plugin>
965+
<groupId>org.apache.maven.plugins</groupId>
966+
<artifactId>maven-shade-plugin</artifactId>
967+
<version>3.5.1</version>
968+
<executions>
969+
<execution>
970+
<phase>package</phase>
971+
<goals>
972+
<goal>shade</goal>
973+
</goals>
974+
</execution>
975+
</executions>
976+
<configuration>
977+
<transformers>
978+
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
979+
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
980+
<mainClass>org.example.embedding.Main</mainClass>
981+
<manifestEntries>
982+
<Multi-Release>true</Multi-Release>
983+
</manifestEntries>
984+
</transformer>
985+
</transformers>
986+
<filters>
987+
<!-- Filters JAR signature files -->
988+
<filter>
989+
<artifact>*:*:*:*</artifact>
990+
<excludes>
991+
<exclude>META-INF/*.SF</exclude>
992+
<exclude>META-INF/*.DSA</exclude>
993+
<exclude>META-INF/*.RSA</exclude>
994+
</excludes>
995+
</filter>
996+
</filters>
997+
</configuration>
998+
</plugin>
999+
</plugins>
1000+
</build>
1001+
</profile>
1002+
```
1003+
1004+
### Maven Assembly plugin
1005+
1006+
If you are using the Maven Assembly plugin, you may apply the following configuration:
1007+
1008+
```xml
1009+
<profile>
1010+
<id>assembly</id>
1011+
<build>
1012+
<plugins>
1013+
<plugin>
1014+
<groupId>org.apache.maven.plugins</groupId>
1015+
<artifactId>maven-assembly-plugin</artifactId>
1016+
<version>3.6.0</version>
1017+
<executions>
1018+
<execution>
1019+
<phase>package</phase>
1020+
<goals>
1021+
<goal>single</goal>
1022+
</goals>
1023+
<configuration>
1024+
<archive>
1025+
<manifest>
1026+
<mainClass>org.example.embedding.Main</mainClass>
1027+
</manifest>
1028+
<manifestEntries>
1029+
<Multi-Release>true</Multi-Release>
1030+
</manifestEntries>
1031+
</archive>
1032+
<descriptors>
1033+
<descriptor>assembly.xml</descriptor>
1034+
</descriptors>
1035+
</configuration>
1036+
</execution>
1037+
</executions>
1038+
</plugin>
1039+
</plugins>
1040+
</build>
1041+
</profile>
1042+
```
1043+
with the corresponding `assembly.xml`:
1044+
1045+
```xml
1046+
<?xml version="1.0" encoding="UTF-8"?>
1047+
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0 http://maven.apache.org/xsd/assembly-2.2.0.xsd">
1048+
<id>jar-with-dependencies</id>
1049+
<formats>
1050+
<format>jar</format>
1051+
</formats>
1052+
<includeBaseDirectory>false</includeBaseDirectory>
1053+
<dependencySets>
1054+
<dependencySet>
1055+
<outputDirectory>/</outputDirectory>
1056+
<useProjectArtifact>true</useProjectArtifact>
1057+
<unpack>true</unpack>
1058+
<scope>runtime</scope>
1059+
</dependencySet>
1060+
</dependencySets>
1061+
<containerDescriptorHandlers>
1062+
<containerDescriptorHandler>
1063+
<handlerName>metaInf-services</handlerName>
1064+
</containerDescriptorHandler>
1065+
</containerDescriptorHandlers>
1066+
</assembly
1067+
```
1068+
9441069
## Compatibility with JSR-223 ScriptEngine
9451070
9461071
<!--

sdk/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ This changelog summarizes major changes between GraalVM SDK versions. The main f
1414
* GR-64488 FileSystem implementations can now provide disk-related metadata, including [total space](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/io/FileSystem.html##getFileStoreTotalSpace(java.nio.file.Path)), [usable space](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/io/FileSystem.html#getFileStoreUsableSpace(java.nio.file.Path)), [unallocated space](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/io/FileSystem.html#getFileStoreUnallocatedSpace(java.nio.file.Path)), [block size](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/io/FileSystem.html#getFileStoreBlockSize(java.nio.file.Path)), and [read-only status](https://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/io/FileSystem.html#isFileStoreReadOnly(java.nio.file.Path)).
1515
* GR-22699(EE-only) Added the ability to spawn `Engine` or `Context` isolated in a separate process by setting `Context.Builder.option("engine.IsolateMode", "external").`.
1616
* GR-64087 Removed the dependency on `org.graalvm.truffle:truffle-enterprise` from all language and tool POM artifacts. As a result, the community Maven artifacts (those with an artifact ID ending in `-community`) are now identical to their corresponding non-community artifacts. Consequently, all community language and tool POM artifacts have been deprecated. The only exception is `org.graalvm.truffle:java-community` vs. `org.graalvm.truffle:java`, which differ in the bundled Java runtime. Embedders using auxiliary engine caching, polyglot isolates, a isolated/untrusted sandbox policy, or the sandbox resource limits must now explicitly add the `org.graalvm.truffle:truffle-enterprise` Maven artifact to the classpath or module path.
17-
* GR-66339 Truffle now checks that `Multi-Release` (JEP 238) classes are loaded correctly, and gives a helpful error if that is not the case.
17+
* GR-66339 Truffle now checks that its multi-release classes ([JEP 238](https://openjdk.org/jeps/238)) are loaded correctly and provides a descriptive error message if they are not.
1818

1919
## Version 24.2.0
2020
* GR-54905 When using Truffle NFI with the Panama backend, native access must now be granted to the Truffle module instead of the NFI Panama module. Use the `--enable-native-access=org.graalvm.truffle` Java command line option to enable the native access for the NFI Panama backend.

truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -107,52 +107,11 @@ private static TruffleRuntimeAccess selectTruffleRuntimeAccess(List<Iterable<Tru
107107

108108
private static TruffleRuntime createRuntime() throws InternalError {
109109
if (!CheckMultiReleaseSupport.isSupported() && !Boolean.getBoolean("polyglotimpl.DisableMultiReleaseCheck")) {
110-
throw new InternalError(
111-
"""
112-
Truffle cannot be loaded because Multi-Release classes are not loaded correctly.
113-
This most likely means Truffle classes have been repackaged incorrectly and the `Multi-Release: true` attribute in META-INF/MANIFEST.MF has been lost.
114-
115-
If you are using the Maven shade plugin, use:
116-
<plugin>
117-
<groupId>org.apache.maven.plugins</groupId>
118-
<artifactId>maven-shade-plugin</artifactId>
119-
<executions>
120-
<execution>
121-
...
122-
<configuration>
123-
<transformers>
124-
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
125-
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
126-
<manifestEntries>
127-
<Multi-Release>true</Multi-Release>
128-
</manifestEntries>
129-
</transformer>
130-
</transformers>
131-
</configuration>
132-
</execution>
133-
</executions>
134-
</plugin>
135-
136-
If you are using the Maven assembly plugin, use:
137-
<plugin>
138-
<groupId>org.apache.maven.plugins</groupId>
139-
<artifactId>maven-assembly-plugin</artifactId>
140-
<executions>
141-
<execution>
142-
...
143-
<configuration>
144-
<archive>
145-
<manifestEntries>
146-
<Multi-Release>true</Multi-Release>
147-
</manifestEntries>
148-
</archive>
149-
</configuration>
150-
</execution>
151-
</executions>
152-
</plugin>
153-
154-
This check can be disabled with '-Dpolyglotimpl.DisableMultiReleaseCheck=true' to unblock things, however that will likely lead to incorrect behavior by using the wrong classes.
155-
""");
110+
throw new InternalError("Truffle could not be initialized because Multi-Release classes are not configured correctly. " +
111+
"This most likely means Truffle classes have been repackaged incorrectly and the `Multi-Release: true` attribute in META-INF/MANIFEST.MF has been lost. " +
112+
"A common cause of this error is invalid Uber JAR configuration. " +
113+
"For more information see: https://www.graalvm.org/latest/reference-manual/embed-languages/#uber-jar-file-creation. " +
114+
"This check may be disabled with '-Dpolyglotimpl.DisableMultiReleaseCheck=true'.");
156115
}
157116

158117
if (Boolean.getBoolean("truffle.UseFallbackRuntime")) {

truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/CheckMultiReleaseSupport.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
*/
4141
package com.oracle.truffle.api.impl;
4242

43+
/*
44+
* Implementation internal class. Please do not use.
45+
*/
4346
public abstract class CheckMultiReleaseSupport {
4447

4548
private CheckMultiReleaseSupport() {

0 commit comments

Comments
 (0)