< prev index next >

src/jdk.jextract/share/classes/com/sun/tools/jextract/JModWriter.java

Print this page

        

@@ -27,23 +27,20 @@
 import java.io.UncheckedIOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import java.util.logging.Level;
 import java.util.spi.ToolProvider;
 import java.util.logging.Logger;
-import jdk.internal.org.objectweb.asm.ClassWriter;
-import jdk.internal.org.objectweb.asm.ModuleVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
 
 // Utility class to generate a .jmod file
 public final class JModWriter {
-    private final Options options;
-    private final Log log;
+    private final Context ctx;
     private final Writer writer;
 
     private static ToolProvider findTool(String name) {
         Optional<ToolProvider> tp = ToolProvider.findFirst(name);
         if (!tp.isPresent()) {

@@ -51,102 +48,112 @@
         }
 
         return tp.get();
     }
 
+    private static final ToolProvider JAVAC = findTool("javac");
     private static final ToolProvider JMOD = findTool("jmod");
 
     public JModWriter(Context ctx, Writer writer) {
-        this.options = ctx.options;
-        this.log = ctx.log;
+        this.ctx = ctx;
         this.writer = writer;
     }
 
     public void writeJModFile(Path jmodFile, String[] args) throws IOException {
-        if (options.targetPackage == null || options.targetPackage.isEmpty()) {
+        if (ctx.options.targetPackage == null || ctx.options.targetPackage.isEmpty()) {
             throw new IllegalArgumentException("no --target-package specified");
         }
 
-        log.print(Level.INFO, () -> "Collecting jmod file " + jmodFile);
+        ctx.log.print(Level.INFO, () -> "Collecting jmod file " + jmodFile);
 
         String modName = jmodFile.getFileName().toString();
         modName = modName.substring(0, modName.length() - 5 /* ".jmod".length() */);
         // FIXME: validate modName
 
         Path jmodRootDir = Files.createTempDirectory("jextract.jmod");
         jmodRootDir.toFile().deleteOnExit();
 
-        log.print(Level.INFO, () -> "Writing .class files");
+        ctx.log.print(Level.INFO, () -> "Writing .class files");
         // write .class files
         Path modClassesDir = jmodRootDir.resolve(modName);
         writer.writeClassFiles(modClassesDir, args);
 
-        log.print(Level.INFO, () -> "Generating module-info.class");
+        ctx.log.print(Level.INFO, () -> "Generating module-info.class");
         // generate module-info.class
-        generateModuleInfoClass(modClassesDir, modName);
+        generateModuleInfoClass(jmodRootDir, modClassesDir, modName);
 
         // copy libraries
         Path libsDir = jmodRootDir.resolve("libs");
         copyNativeLibraries(libsDir);
 
         // generate .jmod file
         generateJMod(modClassesDir, libsDir, jmodFile);
     }
 
-    private void generateModuleInfoClass(Path modClassesDir, String modName) throws IOException {
+    private void generateModuleInfoClass(Path jmodRootDir, Path modClassesDir, String modName) throws IOException {
         // collect package names
         final Set<String> packages = new HashSet<>();
         for (String cls : writer.results().keySet()) {
-            int idx = cls.lastIndexOf("/");
+            int idx = cls.lastIndexOf(".");
             packages.add(cls.substring(0, idx));
         }
 
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
-        cw.visit(Opcodes.V9, Opcodes.ACC_MODULE, "module-info", null, null, null);
-
-        ModuleVisitor mv = cw.visitModule(modName, Opcodes.ACC_MANDATED, null);
-        mv.visitRequire("java.base", Opcodes.ACC_MANDATED, null);
+        // module-info.java source code string
+        StringBuilder modInfoCode = new StringBuilder();
+        modInfoCode.append("module ");
+        modInfoCode.append(modName);
+        modInfoCode.append(" {\n");
         for (String pkg : packages) {
-            mv.visitExport(pkg, Opcodes.ACC_MANDATED);
-        }
-        mv.visitEnd();
-
-        cw.visitEnd();
+            modInfoCode.append("    exports ");
+            modInfoCode.append(pkg);
+            modInfoCode.append(";\n");
+        }
+        modInfoCode.append("}");
+
+        // write module-info.java source in module directory
+        Files.write(modClassesDir.resolve("module-info.java"), List.of(modInfoCode.toString()));
+
+        // compile module-info.java
+        int exitCode = JAVAC.run(ctx.log.getOut(), ctx.log.getErr(),
+            "--module-source-path", jmodRootDir.toString(),
+            "-d", jmodRootDir.toString(),
+            modClassesDir.resolve("module-info.java").toString());
 
-        // write module-info.class source in module directory
-        Files.write(modClassesDir.resolve("module-info.class"), cw.toByteArray());
+        if (exitCode != 0) {
+            throw new RuntimeException("module-info.class generation failed: " + exitCode);
+        }
     }
 
     private void copyNativeLibraries(Path libsDir) throws IOException {
         Files.createDirectory(libsDir);
-        if (!options.libraryNames.isEmpty()) {
-            if (options.libraryPaths.isEmpty()) {
-                log.printWarning("warn.no.library.paths.specified");
+        if (!ctx.options.libraryNames.isEmpty()) {
+            if (ctx.options.libraryPaths.isEmpty()) {
+                ctx.log.printWarning("warn.no.library.paths.specified");
                 return;
             }
-            log.print(Level.INFO, () -> "Copying native libraries");
-            Path[] paths = options.libraryPaths.stream().map(Paths::get).toArray(Path[]::new);
-            options.libraryNames.forEach(libName -> {
+            ctx.log.print(Level.INFO, () -> "Copying native libraries");
+            Path[] paths = ctx.options.libraryPaths.stream().map(Paths::get).toArray(Path[]::new);
+            ctx.options.libraryNames.forEach(libName -> {
                 Optional<Path> absPath = Utils.findLibraryPath(paths, libName);
                 if (absPath.isPresent()) {
                     Path libPath = absPath.get();
                     try {
                         Files.copy(absPath.get(), libsDir.resolve(libPath.getFileName()));
                     } catch (IOException ioExp) {
                         throw new UncheckedIOException(ioExp);
                     }
                 } else {
-                    log.printWarning("warn.library.not.copied", libName);
+                    ctx.log.printWarning("warn.library.not.copied", libName);
                 }
             });
         }
     }
 
     private void generateJMod(Path classesDir, Path libsDir, Path jmodFile)
             throws IOException {
-        log.print(Level.INFO, () -> "Generating jmod file: " + jmodFile);
-        int exitCode = JMOD.run(log.getOut(), log.getErr(), "create",
+        ctx.log.print(Level.INFO, () -> "Generating jmod file: " + jmodFile);
+        int exitCode = JMOD.run(ctx.log.getOut(), ctx.log.getErr(), "create",
             "--class-path", classesDir.toString(),
             "--libs", libsDir.toString(),
             jmodFile.toString());
 
         if (exitCode != 0) {
< prev index next >