< prev index next >

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

Print this page

        

*** 27,49 **** 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.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 Writer writer; private static ToolProvider findTool(String name) { Optional<ToolProvider> tp = ToolProvider.findFirst(name); if (!tp.isPresent()) { --- 27,46 ---- 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; // Utility class to generate a .jmod file public final class JModWriter { ! private final Context ctx; private final Writer writer; private static ToolProvider findTool(String name) { Optional<ToolProvider> tp = ToolProvider.findFirst(name); if (!tp.isPresent()) {
*** 51,152 **** } return tp.get(); } private static final ToolProvider JMOD = findTool("jmod"); public JModWriter(Context ctx, Writer writer) { ! this.options = ctx.options; ! this.log = ctx.log; this.writer = writer; } public void writeJModFile(Path jmodFile, String[] args) throws IOException { ! if (options.targetPackage == null || options.targetPackage.isEmpty()) { throw new IllegalArgumentException("no --target-package specified"); } ! 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"); // write .class files Path modClassesDir = jmodRootDir.resolve(modName); writer.writeClassFiles(modClassesDir, args); ! log.print(Level.INFO, () -> "Generating module-info.class"); // generate module-info.class ! generateModuleInfoClass(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 { // collect package names final Set<String> packages = new HashSet<>(); for (String cls : writer.results().keySet()) { ! 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); for (String pkg : packages) { ! mv.visitExport(pkg, Opcodes.ACC_MANDATED); ! } ! mv.visitEnd(); ! ! cw.visitEnd(); ! // write module-info.class source in module directory ! Files.write(modClassesDir.resolve("module-info.class"), cw.toByteArray()); } 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"); return; } ! log.print(Level.INFO, () -> "Copying native libraries"); ! Path[] paths = options.libraryPaths.stream().map(Paths::get).toArray(Path[]::new); ! 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); } }); } } 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", "--class-path", classesDir.toString(), "--libs", libsDir.toString(), jmodFile.toString()); if (exitCode != 0) { --- 48,159 ---- } return tp.get(); } + private static final ToolProvider JAVAC = findTool("javac"); private static final ToolProvider JMOD = findTool("jmod"); public JModWriter(Context ctx, Writer writer) { ! this.ctx = ctx; this.writer = writer; } public void writeJModFile(Path jmodFile, String[] args) throws IOException { ! if (ctx.options.targetPackage == null || ctx.options.targetPackage.isEmpty()) { throw new IllegalArgumentException("no --target-package specified"); } ! 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(); ! ctx.log.print(Level.INFO, () -> "Writing .class files"); // write .class files Path modClassesDir = jmodRootDir.resolve(modName); writer.writeClassFiles(modClassesDir, args); ! ctx.log.print(Level.INFO, () -> "Generating module-info.class"); // generate module-info.class ! generateModuleInfoClass(jmodRootDir, modClassesDir, modName); // copy libraries Path libsDir = jmodRootDir.resolve("libs"); copyNativeLibraries(libsDir); // generate .jmod file generateJMod(modClassesDir, libsDir, jmodFile); } ! 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("."); packages.add(cls.substring(0, idx)); } ! // module-info.java source code string ! StringBuilder modInfoCode = new StringBuilder(); ! modInfoCode.append("module "); ! modInfoCode.append(modName); ! modInfoCode.append(" {\n"); for (String pkg : packages) { ! 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()); ! if (exitCode != 0) { ! throw new RuntimeException("module-info.class generation failed: " + exitCode); ! } } private void copyNativeLibraries(Path libsDir) throws IOException { Files.createDirectory(libsDir); ! if (!ctx.options.libraryNames.isEmpty()) { ! if (ctx.options.libraryPaths.isEmpty()) { ! ctx.log.printWarning("warn.no.library.paths.specified"); return; } ! 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 { ! ctx.log.printWarning("warn.library.not.copied", libName); } }); } } private void generateJMod(Path classesDir, Path libsDir, Path jmodFile) throws IOException { ! 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 >