26
26
27
27
import static com .oracle .svm .core .SubstrateOptions .IncludeAllFromClassPath ;
28
28
import static com .oracle .svm .core .SubstrateOptions .IncludeAllFromModule ;
29
+ import static com .oracle .svm .core .SubstrateOptions .IncludeAllFromPackage ;
29
30
import static com .oracle .svm .core .SubstrateOptions .IncludeAllFromPath ;
30
31
import static com .oracle .svm .core .util .VMError .guarantee ;
31
32
import static com .oracle .svm .core .util .VMError .shouldNotReachHere ;
74
75
import java .util .stream .Collectors ;
75
76
import java .util .stream .Stream ;
76
77
77
- import com .oracle .svm .core .SubstrateUtil ;
78
78
import org .graalvm .collections .EconomicMap ;
79
79
import org .graalvm .collections .EconomicSet ;
80
80
import org .graalvm .collections .MapCursor ;
81
81
import org .graalvm .nativeimage .impl .AnnotationExtractor ;
82
82
83
83
import com .oracle .svm .core .NativeImageClassLoaderOptions ;
84
84
import com .oracle .svm .core .SubstrateOptions ;
85
+ import com .oracle .svm .core .SubstrateUtil ;
85
86
import com .oracle .svm .core .option .AccumulatingLocatableMultiOptionValue ;
86
87
import com .oracle .svm .core .option .HostedOptionKey ;
87
88
import com .oracle .svm .core .option .LocatableMultiOptionValue .ValueWithOrigin ;
@@ -129,13 +130,15 @@ public final class NativeImageClassLoaderSupport {
129
130
public final AnnotationExtractor annotationExtractor ;
130
131
131
132
private Set <String > javaModuleNamesToInclude ;
133
+ private Set <String > javaPackagesToInclude ;
132
134
private Set <Path > javaPathsToInclude ;
133
135
private boolean includeAllFromClassPath ;
134
136
135
137
private Optional <LibGraalClassLoaderBase > libGraalLoader ;
136
138
private List <ClassLoader > classLoaders ;
137
139
138
- private final Set <Class <?>> classesToIncludeUnconditionally = Collections .newSetFromMap (new ConcurrentHashMap <>());
140
+ private final Set <Class <?>> classesToIncludeUnconditionally = ConcurrentHashMap .newKeySet ();
141
+ private final Set <String > includedJavaPackages = ConcurrentHashMap .newKeySet ();
139
142
140
143
private final Method implAddReadsAllUnnamed = ReflectionUtil .lookupMethod (Module .class , "implAddReadsAllUnnamed" );
141
144
private final Method implAddEnableNativeAccess = ReflectionUtil .lookupMethod (Module .class , "implAddEnableNativeAccess" );
@@ -244,7 +247,7 @@ private static Path stringToPath(String path) {
244
247
}
245
248
246
249
public void loadAllClasses (ForkJoinPool executor , ImageClassLoader imageClassLoader ) {
247
- guarantee (javaModuleNamesToInclude == null , "This method should be executed only once." );
250
+ guarantee (javaModuleNamesToInclude == null && javaPackagesToInclude == null , "This method should be executed only once." );
248
251
javaModuleNamesToInclude = Collections .unmodifiableSet (new HashSet <>(IncludeAllFromModule .getValue (parsedHostedOptions ).values ()));
249
252
/* Verify all modules are present */
250
253
final Set <String > allModules = Stream .concat (modulepathModuleFinder .findAll ().stream (), upgradeAndSystemModuleFinder .findAll ().stream ())
@@ -254,6 +257,8 @@ public void loadAllClasses(ForkJoinPool executor, ImageClassLoader imageClassLoa
254
257
.filter (m -> !allModules .contains (m ))
255
258
.findAny ().ifPresent (m -> missingFromSetOfEntriesError (m , allModules , "module-path" , IncludeAllFromModule ));
256
259
260
+ javaPackagesToInclude = Set .copyOf (IncludeAllFromPackage .getValue (parsedHostedOptions ).values ());
261
+
257
262
javaPathsToInclude = IncludeAllFromPath .getValue (parsedHostedOptions ).values ().stream ()
258
263
.map (NativeImageClassLoaderSupport ::stringToPath )
259
264
.map (Path ::toAbsolutePath )
@@ -722,32 +727,44 @@ private void run() {
722
727
System .out .println ("Total processed entries: " + entriesProcessed .longValue () + ", current entry: " + currentlyProcessedEntry );
723
728
}, 5 , 1 , TimeUnit .MINUTES );
724
729
725
- List <String > requiresInit = new ArrayList <>(Arrays .asList (
726
- "jdk.internal.vm.ci" , "jdk.graal.compiler" , "com.oracle.graal.graal_enterprise" ,
730
+ var requiresInit = new HashSet <>(List .of ("jdk.internal.vm.ci" , "jdk.graal.compiler" , "com.oracle.graal.graal_enterprise" ,
727
731
"org.graalvm.nativeimage" , "org.graalvm.truffle" , "org.graalvm.truffle.runtime" ,
728
732
"org.graalvm.truffle.compiler" , "com.oracle.truffle.enterprise" , "org.graalvm.jniutils" ,
729
733
"org.graalvm.nativebridge" ));
730
734
731
- Set <String > additionalSystemModules = upgradeAndSystemModuleFinder .findAll ().stream ().map (v -> v .descriptor ().name ()).collect (Collectors .toSet ());
735
+ Set <String > additionalSystemModules = upgradeAndSystemModuleFinder .findAll ().stream ()
736
+ .map (v -> v .descriptor ().name ())
737
+ .collect (Collectors .toSet ());
732
738
additionalSystemModules .retainAll (getJavaModuleNamesToInclude ());
733
739
requiresInit .addAll (additionalSystemModules );
734
740
741
+ Set <String > explicitlyAddedModules = ModuleSupport .parseModuleSetModifierProperty (ModuleSupport .PROPERTY_IMAGE_EXPLICITLY_ADDED_MODULES );
742
+
735
743
for (ModuleReference moduleReference : upgradeAndSystemModuleFinder .findAll ()) {
736
- if (requiresInit .contains (moduleReference .descriptor ().name ())) {
737
- initModule (moduleReference );
744
+ String moduleName = moduleReference .descriptor ().name ();
745
+ boolean moduleRequiresInit = requiresInit .contains (moduleName );
746
+ if (moduleRequiresInit || explicitlyAddedModules .contains (moduleName )) {
747
+ initModule (moduleReference , moduleRequiresInit );
738
748
}
739
749
}
740
750
for (ModuleReference moduleReference : modulepathModuleFinder .findAll ()) {
741
- initModule (moduleReference );
751
+ initModule (moduleReference , true );
742
752
}
743
753
744
754
classpath ().parallelStream ().forEach (this ::loadClassesFromPath );
745
755
} finally {
746
756
scheduledExecutor .shutdown ();
747
757
}
758
+
759
+ /* Verify all package inclusion requests were successful */
760
+ for (String packageName : javaPackagesToInclude ) {
761
+ if (!includedJavaPackages .contains (packageName )) {
762
+ missingFromSetOfEntriesError (packageName , includedJavaPackages , "package" , IncludeAllFromPackage );
763
+ }
764
+ }
748
765
}
749
766
750
- private void initModule (ModuleReference moduleReference ) {
767
+ private void initModule (ModuleReference moduleReference , boolean moduleRequiresInit ) {
751
768
String moduleReferenceLocation = moduleReference .location ().map (URI ::toString ).orElse ("UnknownModuleReferenceLocation" );
752
769
currentlyProcessedEntry = moduleReferenceLocation ;
753
770
Optional <Module > optionalModule = findModule (moduleReference .descriptor ().name ());
@@ -766,7 +783,7 @@ private void initModule(ModuleReference moduleReference) {
766
783
String className = extractClassName (moduleResource , fileSystemSeparatorChar );
767
784
if (className != null ) {
768
785
currentlyProcessedEntry = moduleReferenceLocation + fileSystemSeparatorChar + moduleResource ;
769
- executor .execute (() -> handleClassFileName (container , module , className , includeUnconditionally ));
786
+ executor .execute (() -> handleClassFileName (container , module , className , includeUnconditionally , moduleRequiresInit ));
770
787
}
771
788
entriesProcessed .increment ();
772
789
});
@@ -832,7 +849,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
832
849
String className = extractClassName (fileName , fileSystemSeparatorChar );
833
850
if (className != null ) {
834
851
currentlyProcessedEntry = file .toUri ().toString ();
835
- executor .execute (() -> handleClassFileName (container , null , className , includeUnconditionally ));
852
+ executor .execute (() -> handleClassFileName (container , null , className , includeUnconditionally , true ));
836
853
}
837
854
entriesProcessed .increment ();
838
855
return FileVisitResult .CONTINUE ;
@@ -916,24 +933,26 @@ private String extractClassName(String fileName, char fileSystemSeparatorChar) {
916
933
return strippedClassFileName .equals ("module-info" ) ? null : strippedClassFileName .replace (fileSystemSeparatorChar , '.' );
917
934
}
918
935
919
- private void handleClassFileName (URI container , Module module , String className , boolean includeUnconditionally ) {
920
- synchronized (classes ) {
921
- EconomicSet <String > classNames = classes .get (container );
922
- if (classNames == null ) {
923
- classNames = EconomicSet .create ();
924
- classes .put (container , classNames );
936
+ private void handleClassFileName (URI container , Module module , String className , boolean includeUnconditionally , boolean classRequiresInit ) {
937
+ if (classRequiresInit ) {
938
+ synchronized (classes ) {
939
+ EconomicSet <String > classNames = classes .get (container );
940
+ if (classNames == null ) {
941
+ classNames = EconomicSet .create ();
942
+ classes .put (container , classNames );
943
+ }
944
+ classNames .add (className );
925
945
}
926
- classNames . add ( className );
927
- }
928
- int packageSep = className . lastIndexOf ( '.' );
929
- String packageName = packageSep > 0 ? className . substring ( 0 , packageSep ) : "" ;
930
- synchronized ( packages ) {
931
- EconomicSet < String > packageNames = packages . get ( container );
932
- if ( packageNames == null ) {
933
- packageNames = EconomicSet . create ();
934
- packages . put ( container , packageNames );
946
+ int packageSep = className . lastIndexOf ( '.' );
947
+ String packageName = packageSep > 0 ? className . substring ( 0 , packageSep ) : "" ;
948
+ synchronized ( packages ) {
949
+ EconomicSet < String > packageNames = packages . get ( container ) ;
950
+ if ( packageNames == null ) {
951
+ packageNames = EconomicSet . create ( );
952
+ packages . put ( container , packageNames );
953
+ }
954
+ packageNames . add ( packageName );
935
955
}
936
- packageNames .add (packageName );
937
956
}
938
957
939
958
Class <?> clazz = null ;
@@ -945,10 +964,14 @@ private void handleClassFileName(URI container, Module module, String className,
945
964
ImageClassLoader .handleClassLoadingError (t );
946
965
}
947
966
if (clazz != null ) {
948
- if (includeUnconditionally ) {
967
+ String packageName = clazz .getPackageName ();
968
+ includedJavaPackages .add (packageName );
969
+ if (includeUnconditionally || javaPackagesToInclude .contains (packageName )) {
949
970
classesToIncludeUnconditionally .add (clazz );
950
971
}
951
- imageClassLoader .handleClass (clazz );
972
+ if (classRequiresInit ) {
973
+ imageClassLoader .handleClass (clazz );
974
+ }
952
975
}
953
976
imageClassLoader .watchdog .recordActivity ();
954
977
}
0 commit comments