import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
+import java.util.stream.Collectors;
import java.util.zip.Deflater;
import org.eclipse.jdt.core.compiler.CompilationProgress;
import aQute.bnd.osgi.Analyzer;
import aQute.bnd.osgi.Jar;
+import aQute.bnd.osgi.Resource;
+import aQute.bnd.plugin.jpms.JPMSModuleInfoPlugin;
/**
* Minimalistic OSGi compiler and packager, meant to be used as a single file
List<String> a2Categories = options.getOrDefault("--dep-categories", new ArrayList<>());
List<String> a2Bases = options.getOrDefault("--a2-bases", new ArrayList<>());
- if (a2Bases.isEmpty() || !a2Bases.contains(a2Output.toString())) {
+ a2Bases = a2Bases.stream().distinct().collect(Collectors.toList());// remove duplicates
+ if (a2Bases.isEmpty() || !a2Bases.contains(a2Output.toString())) {// make sure a2 output is available
a2Bases.add(a2Output.toString());
}
A2Jar current = a2Jars.get(a2Jar.name);
if (a2Jar.major > current.major)
a2Jars.put(a2Jar.name, a2Jar);
- else if (a2Jar.major == current.major //
- // if minor equals, we take the last one
- && a2Jar.minor >= current.minor)
+ else if (a2Jar.major == current.major && a2Jar.minor > current.minor)
a2Jars.put(a2Jar.name, a2Jar);
+ // keep if minor equals
} else {
a2Jars.put(a2Jar.name, a2Jar);
}
void deleteEmptyParents(Path baseDir, Path targetParent) throws IOException {
if (!targetParent.startsWith(baseDir))
throw new IllegalArgumentException(targetParent + " does not start with " + baseDir);
- if (!Files.exists(targetParent))
+ if (!Files.exists(baseDir))
+ return;
+ if (!Files.exists(targetParent)) {
deleteEmptyParents(baseDir, targetParent.getParent());
+ return;
+ }
if (!Files.isDirectory(targetParent))
throw new IllegalArgumentException(targetParent + " must be a directory");
boolean isA2target = Files.isSameFile(baseDir, targetParent);
if (!Files.exists(binP))
Files.createDirectories(binP);
Manifest manifest;
+ Resource moduleInfoClass = null;
try (Analyzer bndAnalyzer = new Analyzer()) {
bndAnalyzer.setProperties(properties);
Jar jar = new Jar(bundleSymbolicName, binP.toFile());
bndAnalyzer.setJar(jar);
manifest = bndAnalyzer.calcManifest();
+
+ // JPMS module
+ jar.setManifest(manifest);
+ JPMSModuleInfoPlugin jpmsModuleInfoPlugin = new JPMSModuleInfoPlugin();
+ jpmsModuleInfoPlugin.verify(bndAnalyzer);
+ moduleInfoClass = bndAnalyzer.getJar().getResource("module-info.class");
} catch (Exception e) {
throw new RuntimeException("Bnd analysis of " + compiled + " failed", e);
}
manifest.write(out);
}
+ // Write module-info.class
+ if (moduleInfoClass != null) {
+ Path moduleInfoClassP = compiled.resolve("module-info.class");
+ Files.createDirectories(moduleInfoClassP.getParent());
+ try (OutputStream out = Files.newOutputStream(moduleInfoClassP)) {
+ moduleInfoClass.write(out);
+ logger.log(INFO, "Wrote " + moduleInfoClassP);
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot write module-info.class");
+ }
+ }
+
// Load excludes
List<PathMatcher> excludes = new ArrayList<>();
Path excludesP = argeoBuildBase.resolve("excludes.txt");