use of dev.jbang.cli.BaseCommand.EXIT_UNEXPECTED_STATE in project jbang by jbangdev.
the class IntegrationManager method runIntegration.
/**
* Discovers all integration points and runs them.
* <p>
* If an integration point created a native image it returns the resulting
* image.
*
* @param repositories
* @param artifacts
* @param tmpJarDir
* @param pomPath
* @param source
* @param nativeRequested
* @return
*/
public static IntegrationResult runIntegration(List<MavenRepo> repositories, List<ArtifactInfo> artifacts, Path tmpJarDir, Path pomPath, Source source, boolean nativeRequested) {
URL[] urls = artifacts.stream().map(s -> {
try {
return s.getFile().toURI().toURL();
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}).toArray(URL[]::new);
List<String> comments = source.getLines().stream().filter(s -> s.startsWith("//")).collect(Collectors.toList());
URLClassLoader integrationCl = new URLClassLoader(urls);
ClassLoader old = Thread.currentThread().getContextClassLoader();
Map<String, byte[]> data = new HashMap<>();
List<Map.Entry<String, String>> repos = null;
List<Map.Entry<String, Path>> deps = null;
Path nativeImage = null;
String mainClass = null;
List<String> javaArgs = null;
PrintStream oldout = System.out;
try {
// TODO: should we add new properties to the integration method?
if (source.getResourceRef().getFile() != null) {
System.setProperty("jbang.source", source.getResourceRef().getFile().getAbsolutePath());
}
Thread.currentThread().setContextClassLoader(integrationCl);
Set<String> classNames = loadIntegrationClassNames(integrationCl);
for (String className : classNames) {
if (repos == null) {
repos = repositories.stream().map(s -> new MapRepoEntry(s.getId(), s.getUrl())).collect(Collectors.toList());
}
if (deps == null) {
deps = artifacts.stream().map(s -> new MapEntry(s.getCoordinate().toCanonicalForm(), s.getFile().toPath())).collect(Collectors.toList());
}
Class<?> clazz = Class.forName(className, true, integrationCl);
Method method = clazz.getDeclaredMethod("postBuild", Path.class, Path.class, List.class, List.class, List.class, boolean.class);
Util.infoMsg("Post build with " + className);
if (Util.isVerbose()) {
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.err)));
} else {
System.setOut(new PrintStream(new OutputStream() {
public void write(int b) {
// DO NOTHING
// TODO: capture it for later print if error
}
}));
}
@SuppressWarnings("unchecked") Map<String, Object> integrationResult = (Map<String, Object>) method.invoke(null, tmpJarDir, pomPath, repos, deps, comments, nativeRequested);
@SuppressWarnings("unchecked") Map<String, byte[]> ret = (Map<String, byte[]>) integrationResult.get(FILES);
if (ret != null) {
data.putAll(ret);
}
Path image = (Path) integrationResult.get(NATIVE_IMAGE);
if (image != null) {
nativeImage = image;
}
String mc = (String) integrationResult.get(MAIN_CLASS);
if (mc != null) {
mainClass = mc;
}
@SuppressWarnings("unchecked") List<String> ja = (List<String>) integrationResult.get(JAVA_ARGS);
if (ja != null) {
javaArgs = ja;
}
}
for (Map.Entry<String, byte[]> entry : data.entrySet()) {
Path target = tmpJarDir.resolve(entry.getKey());
Files.createDirectories(target.getParent());
try (OutputStream out = Files.newOutputStream(target)) {
out.write(entry.getValue());
}
}
} catch (ClassNotFoundException e) {
throw new ExitException(EXIT_UNEXPECTED_STATE, "Unable to load integration class", e);
} catch (NoSuchMethodException e) {
throw new ExitException(EXIT_UNEXPECTED_STATE, "Integration class missing method with signature public static Map<String, byte[]> postBuild(Path classesDir, Path pomFile, List<Map.Entry<String, Path>> dependencies)", e);
} catch (Exception e) {
throw new ExitException(EXIT_UNEXPECTED_STATE, "Issue running postBuild()", e);
} finally {
Thread.currentThread().setContextClassLoader(old);
System.setOut(oldout);
}
return new IntegrationResult(nativeImage, mainClass, javaArgs);
}
Aggregations