4747import java .nio .file .Files ;
4848import java .util .ArrayList ;
4949import java .util .Collection ;
50+ import java .util .Collections ;
51+ import java .util .TreeSet ;
5052import java .util .LinkedHashMap ;
5153import java .util .List ;
5254import java .util .Map ;
5355import java .util .Optional ;
56+ import java .util .Set ;
5457import java .util .jar .JarEntry ;
5558import java .util .jar .JarInputStream ;
5659import java .util .jar .JarOutputStream ;
@@ -197,8 +200,9 @@ private void addAutomaticModuleName(File originalJar, File moduleJar, AutomaticM
197200 manifest .getMainAttributes ().putValue ("Automatic-Module-Name" , automaticModule .getModuleName ());
198201 try (JarOutputStream outputStream = new JarOutputStream (Files .newOutputStream (moduleJar .toPath ()), manifest )) {
199202 Map <String , List <String >> providers = new LinkedHashMap <>();
200- copyAndExtractProviders (inputStream , outputStream , !automaticModule .getMergedJars ().isEmpty (), providers );
201- mergeJars (automaticModule , outputStream , providers );
203+ Set <String > packages = new TreeSet <>();
204+ copyAndExtractProviders (inputStream , outputStream , !automaticModule .getMergedJars ().isEmpty (), providers , packages );
205+ mergeJars (automaticModule , outputStream , providers , packages );
202206 }
203207 } catch (IOException e ) {
204208 throw new RuntimeException (e );
@@ -209,10 +213,12 @@ private void addModuleDescriptor(File originalJar, File moduleJar, ModuleInfo mo
209213 try (JarInputStream inputStream = new JarInputStream (Files .newInputStream (originalJar .toPath ()))) {
210214 try (JarOutputStream outputStream = newJarOutputStream (Files .newOutputStream (moduleJar .toPath ()), inputStream .getManifest ())) {
211215 Map <String , List <String >> providers = new LinkedHashMap <>();
212- copyAndExtractProviders (inputStream , outputStream , !moduleInfo .getMergedJars ().isEmpty (), providers );
213- mergeJars (moduleInfo , outputStream , providers );
216+ Set <String > packages = new TreeSet <>();
217+ copyAndExtractProviders (inputStream , outputStream , !moduleInfo .getMergedJars ().isEmpty (), providers , packages );
218+ mergeJars (moduleInfo , outputStream , providers , packages );
214219 outputStream .putNextEntry (new JarEntry ("module-info.class" ));
215- outputStream .write (addModuleInfo (moduleInfo , providers , versionFromFilePath (originalJar .toPath ())));
220+ outputStream .write (addModuleInfo (moduleInfo , providers , versionFromFilePath (originalJar .toPath ()),
221+ moduleInfo .getExportAllPackages () ? packages : Collections .emptySet ()));
216222 outputStream .closeEntry ();
217223 }
218224 } catch (IOException e ) {
@@ -224,7 +230,7 @@ private JarOutputStream newJarOutputStream(OutputStream out, @Nullable Manifest
224230 return manifest == null ? new JarOutputStream (out ) : new JarOutputStream (out , manifest );
225231 }
226232
227- private void copyAndExtractProviders (JarInputStream inputStream , JarOutputStream outputStream , boolean willMergeJars , Map <String , List <String >> providers ) throws IOException {
233+ private void copyAndExtractProviders (JarInputStream inputStream , JarOutputStream outputStream , boolean willMergeJars , Map <String , List <String >> providers , Set < String > packages ) throws IOException {
228234 JarEntry jarEntry = inputStream .getNextJarEntry ();
229235 while (jarEntry != null ) {
230236 byte [] content = readAllBytes (inputStream );
@@ -238,7 +244,7 @@ private void copyAndExtractProviders(JarInputStream inputStream, JarOutputStream
238244 providers .get (key ).addAll (extractImplementations (content ));
239245 }
240246
241- if (!JAR_SIGNATURE_PATH .matcher (jarEntry . getName () ).matches () && !"META-INF/MANIFEST.MF" .equals (jarEntry .getName ())) {
247+ if (!JAR_SIGNATURE_PATH .matcher (entryName ).matches () && !"META-INF/MANIFEST.MF" .equals (jarEntry .getName ())) {
242248 if (!willMergeJars || !isServiceProviderFile ) { // service provider files will be merged later
243249 jarEntry .setCompressedSize (-1 );
244250 try {
@@ -250,6 +256,12 @@ private void copyAndExtractProviders(JarInputStream inputStream, JarOutputStream
250256 throw new RuntimeException (e );
251257 }
252258 }
259+ if (entryName .endsWith (".class" )) {
260+ int i = entryName .lastIndexOf ("/" );
261+ if (i > 0 ) {
262+ packages .add (entryName .substring (0 , i ));
263+ }
264+ }
253265 }
254266 }
255267 jarEntry = inputStream .getNextJarEntry ();
@@ -266,11 +278,14 @@ private List<String> extractImplementations(byte[] content) {
266278 .collect (Collectors .toList ());
267279 }
268280
269- private byte [] addModuleInfo (ModuleInfo moduleInfo , Map <String , List <String >> providers , @ Nullable String version ) {
281+ private byte [] addModuleInfo (ModuleInfo moduleInfo , Map <String , List <String >> providers , @ Nullable String version , Set < String > autoExportedPackages ) {
270282 ClassWriter classWriter = new ClassWriter (0 );
271283 classWriter .visit (Opcodes .V9 , Opcodes .ACC_MODULE , "module-info" , null , null , null );
272284 String moduleVersion = moduleInfo .getModuleVersion () == null ? version : moduleInfo .getModuleVersion ();
273285 ModuleVisitor moduleVisitor = classWriter .visitModule (moduleInfo .getModuleName (), Opcodes .ACC_OPEN , moduleVersion );
286+ for (String packageName : autoExportedPackages ) {
287+ moduleVisitor .visitExport (packageName , 0 );
288+ }
274289 for (String packageName : moduleInfo .exports ) {
275290 moduleVisitor .visitExport (packageName .replace ('.' , '/' ), 0 );
276291 }
@@ -297,7 +312,7 @@ private byte[] addModuleInfo(ModuleInfo moduleInfo, Map<String, List<String>> pr
297312 return classWriter .toByteArray ();
298313 }
299314
300- private void mergeJars (ModuleSpec moduleSpec , JarOutputStream outputStream , Map <String , List <String >> providers ) throws IOException {
315+ private void mergeJars (ModuleSpec moduleSpec , JarOutputStream outputStream , Map <String , List <String >> providers , Set < String > packages ) throws IOException {
301316 if (moduleSpec .getMergedJars ().isEmpty ()) {
302317 return ;
303318 }
@@ -321,7 +336,7 @@ private void mergeJars(ModuleSpec moduleSpec, JarOutputStream outputStream, Map<
321336
322337 if (mergeJarFile != null ) {
323338 try (JarInputStream toMergeInputStream = new JarInputStream (Files .newInputStream (mergeJarFile .getAsFile ().toPath ()))) {
324- copyAndExtractProviders (toMergeInputStream , outputStream , true , providers );
339+ copyAndExtractProviders (toMergeInputStream , outputStream , true , providers , packages );
325340 }
326341 } else {
327342 throw new RuntimeException ("Jar not found: " + identifier );
0 commit comments