< 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 >