Search in sources :

Example 1 with EXIT_UNEXPECTED_STATE

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);
}
Also used : Enumeration(java.util.Enumeration) URL(java.net.URL) HashMap(java.util.HashMap) MavenRepo(dev.jbang.dependencies.MavenRepo) Source(dev.jbang.source.Source) ExitException(dev.jbang.cli.ExitException) ArtifactInfo(dev.jbang.dependencies.ArtifactInfo) HashSet(java.util.HashSet) URLClassLoader(java.net.URLClassLoader) Map(java.util.Map) Method(java.lang.reflect.Method) Path(java.nio.file.Path) OutputStream(java.io.OutputStream) PrintStream(java.io.PrintStream) Util(dev.jbang.util.Util) MalformedURLException(java.net.MalformedURLException) Files(java.nio.file.Files) FileOutputStream(java.io.FileOutputStream) Set(java.util.Set) IOException(java.io.IOException) InputStreamReader(java.io.InputStreamReader) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) List(java.util.List) EXIT_UNEXPECTED_STATE(dev.jbang.cli.BaseCommand.EXIT_UNEXPECTED_STATE) FileDescriptor(java.io.FileDescriptor) BufferedReader(java.io.BufferedReader) InputStream(java.io.InputStream) MalformedURLException(java.net.MalformedURLException) HashMap(java.util.HashMap) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) URL(java.net.URL) URLClassLoader(java.net.URLClassLoader) List(java.util.List) ExitException(dev.jbang.cli.ExitException) Path(java.nio.file.Path) PrintStream(java.io.PrintStream) Method(java.lang.reflect.Method) ExitException(dev.jbang.cli.ExitException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) URLClassLoader(java.net.URLClassLoader) FileOutputStream(java.io.FileOutputStream) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

EXIT_UNEXPECTED_STATE (dev.jbang.cli.BaseCommand.EXIT_UNEXPECTED_STATE)1 ExitException (dev.jbang.cli.ExitException)1 ArtifactInfo (dev.jbang.dependencies.ArtifactInfo)1 MavenRepo (dev.jbang.dependencies.MavenRepo)1 Source (dev.jbang.source.Source)1 Util (dev.jbang.util.Util)1 BufferedReader (java.io.BufferedReader)1 FileDescriptor (java.io.FileDescriptor)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 InputStreamReader (java.io.InputStreamReader)1 OutputStream (java.io.OutputStream)1 PrintStream (java.io.PrintStream)1 Method (java.lang.reflect.Method)1 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 URLClassLoader (java.net.URLClassLoader)1 StandardCharsets (java.nio.charset.StandardCharsets)1 Files (java.nio.file.Files)1