5454import java .lang .reflect .Method ;
5555import java .net .URI ;
5656import java .nio .ByteBuffer ;
57+ import java .nio .file .Files ;
5758import java .nio .file .Path ;
5859import java .util .ArrayDeque ;
5960import java .util .Collections ;
8384import jdk .internal .access .JavaLangAccess ;
8485import jdk .internal .access .SharedSecrets ;
8586import jdk .internal .module .Modules ;
87+ import org .graalvm .collections .Pair ;
8688
8789final class JDKSupport {
8890
@@ -108,36 +110,57 @@ final class JDKSupport {
108110 }
109111 }
110112
111- private static final ModulesAccessor MODULES_ACCESSOR = initializeModuleAccessor ();
113+ /**
114+ * Represents either a {@code ModuleAccessor} or an error message.
115+ * <p>
116+ * The following combinations are valid:
117+ * <ul>
118+ * <li>{@code {moduleAccessor, null}} - a successful result with a module accessor.</li>
119+ * <li>{@code {null, errorMessage}} - a failure with an error message.</li>
120+ * </ul>
121+ */
122+ private static final Pair <ModulesAccessor , String > MODULES_ACCESSOR = initializeModuleAccessor ();
112123
113124 @ SuppressWarnings ("restricted" )
114- private static ModulesAccessor initializeModuleAccessor () {
125+ private static Pair < ModulesAccessor , String > initializeModuleAccessor () {
115126 String attachLibPath = System .getProperty ("truffle.attach.library" );
116127 if (attachLibPath == null ) {
117128 if (isUnsupportedPlatform ()) {
118- performTruffleAttachLoadFailureAction ("Truffle is running on an unsupported platform where the TruffleAttach library is unavailable." , null );
119- return null ;
129+ String errorMessage = "Truffle is running on an unsupported platform where the TruffleAttach library is unavailable." ;
130+ performTruffleAttachLoadFailureAction (errorMessage , null );
131+ return Pair .create (null , errorMessage );
120132 }
133+ InternalResource libTruffleAttachResource = new LibTruffleAttachResource ();
121134 try {
122- Path truffleAttachRoot = InternalResourceCache .installRuntimeResource (new LibTruffleAttachResource () , LibTruffleAttachResource .ID );
135+ Path truffleAttachRoot = InternalResourceCache .installRuntimeResource (libTruffleAttachResource , LibTruffleAttachResource .ID );
123136 Path libAttach = truffleAttachRoot .resolve ("bin" ).resolve (System .mapLibraryName ("truffleattach" ));
124137 attachLibPath = libAttach .toString ();
125138 } catch (IOException ioe ) {
126- performTruffleAttachLoadFailureAction ("The Truffle API JAR is missing the 'truffleattach' resource, likely due to issues when Truffle was repackaged into a fat JAR." , ioe );
127- return null ;
139+ String errorMessage ;
140+ InternalResourceCache cache = InternalResourceCache .createRuntimeResourceCache (libTruffleAttachResource , LibTruffleAttachResource .ID );
141+ Path root = cache .getOwningRoot ();
142+ if (root == null || !Files .isDirectory (root ) || !Files .isReadable (root ) || !Files .isWritable (root )) {
143+ errorMessage = String .format ("Failed to install the 'truffleattach' resource: the resource cache folder %s is not a readable and writable directory." , root );
144+ } else {
145+ errorMessage = "The Truffle API JAR is missing the 'truffleattach' resource, likely due to issues when Truffle was repackaged into a fat JAR." ;
146+ }
147+ performTruffleAttachLoadFailureAction (errorMessage , ioe );
148+ return Pair .create (null , errorMessage );
128149 }
129150 }
130151 try {
131152 try {
132153 System .load (attachLibPath );
133154 } catch (UnsatisfiedLinkError failedToLoad ) {
134- performTruffleAttachLoadFailureAction ("Unable to load the TruffleAttach library." , failedToLoad );
135- return null ;
155+ String errorMessage = String .format ("Unable to load the TruffleAttach library %s" , attachLibPath );
156+ performTruffleAttachLoadFailureAction (errorMessage , failedToLoad );
157+ return Pair .create (null , errorMessage );
136158 } catch (IllegalCallerException illegalCaller ) {
137159 String vmOption = "--enable-native-access=" + (JDKSupport .class .getModule ().isNamed () ? "org.graalvm.truffle" : "ALL-UNNAMED" );
138- performTruffleAttachLoadFailureAction (String .format ("Failed to load the TruffleAttach library. The Truffle module does not have native access enabled. " +
139- "To resolve this, pass the following VM option: %s." , vmOption ), illegalCaller );
140- return null ;
160+ String errorMessage = String .format ("Failed to load the TruffleAttach library. The Truffle module does not have native access enabled. " +
161+ "To resolve this, pass the following VM option: %s." , vmOption );
162+ performTruffleAttachLoadFailureAction (errorMessage , illegalCaller );
163+ return Pair .create (null , errorMessage );
141164 }
142165 ModulesAccessor accessor ;
143166 if (ModulesAccessor .class .getModule ().isNamed ()) {
@@ -148,7 +171,7 @@ private static ModulesAccessor initializeModuleAccessor() {
148171 Module javaBase = ModuleLayer .boot ().findModule ("java.base" ).orElseThrow ();
149172 addExports0 (javaBase , "jdk.internal.module" , accessor .getTargetModule ());
150173 addExports0 (javaBase , "jdk.internal.access" , accessor .getTargetModule ());
151- return accessor ;
174+ return Pair . create ( accessor , null ) ;
152175 } catch (ReflectiveOperationException re ) {
153176 throw new InternalError (re );
154177 }
@@ -235,7 +258,11 @@ static void enableNativeAccess(Module clientModule) {
235258
236259 @ SuppressWarnings ("restricted" )
237260 static ModulesAccessor getModulesAccessor () {
238- return MODULES_ACCESSOR ;
261+ return MODULES_ACCESSOR .getLeft ();
262+ }
263+
264+ static String getInitializationErrorMessage () {
265+ return MODULES_ACCESSOR .getRight ();
239266 }
240267
241268 private static void forEach (Module rootModule , Set <Edge > edges , Predicate <? super Module > filter , Consumer <? super Module > action ) {
@@ -699,10 +726,10 @@ private static final class JavaLangSupportImpl extends JavaLangSupport {
699726 static {
700727 if (JDKSupport .MODULES_ACCESSOR == null ) {
701728 throw new IllegalStateException ("JavaLangAccessorImpl initialized before JDKSupport." );
702- } else if (!(JDKSupport .MODULES_ACCESSOR instanceof IsolatedImpl )) {
729+ } else if (!(JDKSupport .MODULES_ACCESSOR . getLeft () instanceof IsolatedImpl )) {
703730 throw new IllegalStateException ("JDKSupport.MODULES_ACCESSOR initialized with wrong type " + JDKSupport .MODULES_ACCESSOR .getClass ());
704731 } else {
705- CURRENT_CARRIER_THREAD = ((IsolatedImpl ) JDKSupport .MODULES_ACCESSOR ).currentCarrierThread ;
732+ CURRENT_CARRIER_THREAD = ((IsolatedImpl ) JDKSupport .MODULES_ACCESSOR . getLeft () ).currentCarrierThread ;
706733 }
707734 }
708735
0 commit comments