34
34
import java .util .Map ;
35
35
import java .util .Optional ;
36
36
import java .util .concurrent .atomic .AtomicBoolean ;
37
+ import java .util .function .Predicate ;
37
38
import java .util .function .Supplier ;
38
39
import java .util .regex .Matcher ;
39
40
import java .util .regex .Pattern ;
40
41
import java .util .stream .Collectors ;
42
+ import java .util .zip .ZipEntry ;
43
+ import java .util .zip .ZipFile ;
44
+ import jdk .jpackage .test .Functional .ThrowingConsumer ;
41
45
import jdk .jpackage .test .Functional .ThrowingFunction ;
42
46
import jdk .jpackage .test .Functional .ThrowingSupplier ;
43
47
@@ -225,16 +229,15 @@ static void verifyOutputFile(Path outputFile, List<String> args,
225
229
public static Path createBundle (JavaAppDesc appDesc , Path outputDir ) {
226
230
String jmodFileName = appDesc .jmodFileName ();
227
231
if (jmodFileName != null ) {
228
- final Path jmodFilePath = outputDir .resolve (jmodFileName );
232
+ final Path jmodPath = outputDir .resolve (jmodFileName );
229
233
TKit .withTempDirectory ("jmod-workdir" , jmodWorkDir -> {
230
234
var jarAppDesc = JavaAppDesc .parse (appDesc .toString ())
231
235
.setBundleFileName ("tmp.jar" );
232
236
Path jarPath = createBundle (jarAppDesc , jmodWorkDir );
233
237
Executor exec = new Executor ()
234
238
.setToolProvider (JavaTool .JMOD )
235
239
.addArguments ("create" , "--class-path" )
236
- .addArgument (jarPath )
237
- .addArgument (jmodFilePath );
240
+ .addArgument (jarPath );
238
241
239
242
if (appDesc .isWithMainClass ()) {
240
243
exec .addArguments ("--main-class" , appDesc .className ());
@@ -244,11 +247,50 @@ public static Path createBundle(JavaAppDesc appDesc, Path outputDir) {
244
247
exec .addArguments ("--module-version" , appDesc .moduleVersion ());
245
248
}
246
249
247
- Files .createDirectories (jmodFilePath .getParent ());
250
+ final Path jmodFilePath ;
251
+ if (appDesc .isExplodedModule ()) {
252
+ jmodFilePath = jmodWorkDir .resolve ("tmp.jmod" );
253
+ exec .addArgument (jmodFilePath );
254
+ TKit .deleteDirectoryRecursive (jmodPath );
255
+ } else {
256
+ jmodFilePath = jmodPath ;
257
+ exec .addArgument (jmodFilePath );
258
+ TKit .deleteIfExists (jmodPath );
259
+ }
260
+
261
+ Files .createDirectories (jmodPath .getParent ());
248
262
exec .execute ();
263
+
264
+ if (appDesc .isExplodedModule ()) {
265
+ TKit .trace (String .format ("Explode [%s] module file..." ,
266
+ jmodFilePath .toAbsolutePath ().normalize ()));
267
+ // Explode contents of the root `classes` directory of
268
+ // temporary .jmod file
269
+ final Path jmodRootDir = Path .of ("classes" );
270
+ try (var archive = new ZipFile (jmodFilePath .toFile ())) {
271
+ archive .stream ()
272
+ .filter (Predicate .not (ZipEntry ::isDirectory ))
273
+ .sequential ().forEachOrdered (ThrowingConsumer .toConsumer (
274
+ entry -> {
275
+ try (var in = archive .getInputStream (entry )) {
276
+ Path entryName = Path .of (entry .getName ());
277
+ if (entryName .startsWith (jmodRootDir )) {
278
+ entryName = jmodRootDir .relativize (entryName );
279
+ }
280
+ final Path fileName = jmodPath .resolve (entryName );
281
+ TKit .trace (String .format (
282
+ "Save [%s] zip entry in [%s] file..." ,
283
+ entry .getName (),
284
+ fileName .toAbsolutePath ().normalize ()));
285
+ Files .createDirectories (fileName .getParent ());
286
+ Files .copy (in , fileName );
287
+ }
288
+ }));
289
+ }
290
+ }
249
291
});
250
292
251
- return jmodFilePath ;
293
+ return jmodPath ;
252
294
}
253
295
254
296
final JavaAppDesc jarAppDesc ;
0 commit comments