Search in sources :

Example 1 with TransformedClassesBuildItem

use of io.quarkus.deployment.builditem.TransformedClassesBuildItem in project quarkus by quarkusio.

the class JarResultBuildStep method handleAppCDSSupportFileGeneration.

// the idea here is to just dump the class names of the generated and transformed classes into a file
// that is read at runtime when AppCDS generation is requested
private void handleAppCDSSupportFileGeneration(TransformedClassesBuildItem transformedClasses, List<GeneratedClassBuildItem> generatedClasses, AppCDSRequestedBuildItem appCDS) throws IOException {
    Path appCDsDir = appCDS.getAppCDSDir();
    Path generatedClassesFile = appCDsDir.resolve("generatedAndTransformed.lst");
    try (BufferedWriter writer = Files.newBufferedWriter(generatedClassesFile, StandardOpenOption.CREATE)) {
        StringBuilder classes = new StringBuilder();
        for (GeneratedClassBuildItem generatedClass : generatedClasses) {
            classes.append(generatedClass.getName().replace('/', '.')).append(System.lineSeparator());
        }
        for (Set<TransformedClassesBuildItem.TransformedClass> transformedClassesSet : transformedClasses.getTransformedClassesByJar().values()) {
            for (TransformedClassesBuildItem.TransformedClass transformedClass : transformedClassesSet) {
                if (transformedClass.getData() != null) {
                    classes.append(transformedClass.getFileName().replace('/', '.').replace(".class", "")).append(System.lineSeparator());
                }
            }
        }
        if (classes.length() != 0) {
            writer.write(classes.toString());
        }
    }
}
Also used : Path(java.nio.file.Path) TransformedClassesBuildItem(io.quarkus.deployment.builditem.TransformedClassesBuildItem) GeneratedClassBuildItem(io.quarkus.deployment.builditem.GeneratedClassBuildItem) BufferedWriter(java.io.BufferedWriter)

Example 2 with TransformedClassesBuildItem

use of io.quarkus.deployment.builditem.TransformedClassesBuildItem in project quarkus by quarkusio.

the class StartupActionImpl method extractTransformers.

private Map<String, byte[]> extractTransformers(Set<String> eagerClasses) {
    Map<String, byte[]> ret = new HashMap<>();
    TransformedClassesBuildItem transformers = buildResult.consume(TransformedClassesBuildItem.class);
    for (Set<TransformedClassesBuildItem.TransformedClass> i : transformers.getTransformedClassesByJar().values()) {
        for (TransformedClassesBuildItem.TransformedClass clazz : i) {
            if (clazz.getData() != null) {
                ret.put(clazz.getFileName(), clazz.getData());
                if (clazz.isEager()) {
                    eagerClasses.add(clazz.getClassName());
                }
            }
        }
    }
    return ret;
}
Also used : TransformedClassesBuildItem(io.quarkus.deployment.builditem.TransformedClassesBuildItem) HashMap(java.util.HashMap)

Example 3 with TransformedClassesBuildItem

use of io.quarkus.deployment.builditem.TransformedClassesBuildItem in project quarkus by quarkusio.

the class ClassTransformingBuildStep method handleClassTransformation.

@BuildStep
TransformedClassesBuildItem handleClassTransformation(List<BytecodeTransformerBuildItem> bytecodeTransformerBuildItems, ApplicationArchivesBuildItem appArchives, LiveReloadBuildItem liveReloadBuildItem, LaunchModeBuildItem launchModeBuildItem, ClassLoadingConfig classLoadingConfig, CurateOutcomeBuildItem curateOutcomeBuildItem, List<RemovedResourceBuildItem> removedResourceBuildItems, ArchiveRootBuildItem archiveRoot, LaunchModeBuildItem launchMode, PackageConfig packageConfig) throws ExecutionException, InterruptedException {
    if (bytecodeTransformerBuildItems.isEmpty() && classLoadingConfig.removedResources.isEmpty() && removedResourceBuildItems.isEmpty()) {
        return new TransformedClassesBuildItem(Collections.emptyMap());
    }
    final Map<String, List<BytecodeTransformerBuildItem>> bytecodeTransformers = new HashMap<>(bytecodeTransformerBuildItems.size());
    Set<String> noConstScanning = new HashSet<>();
    Map<String, Set<String>> constScanning = new HashMap<>();
    Set<String> eager = new HashSet<>();
    Set<String> nonCacheable = new HashSet<>();
    Map<String, Integer> classReaderOptions = new HashMap<>();
    for (BytecodeTransformerBuildItem i : bytecodeTransformerBuildItems) {
        bytecodeTransformers.computeIfAbsent(i.getClassToTransform(), (h) -> new ArrayList<>()).add(i);
        if (i.getRequireConstPoolEntry() == null || i.getRequireConstPoolEntry().isEmpty()) {
            noConstScanning.add(i.getClassToTransform());
        } else {
            constScanning.computeIfAbsent(i.getClassToTransform(), (s) -> new HashSet<>()).addAll(i.getRequireConstPoolEntry());
        }
        if (i.isEager()) {
            eager.add(i.getClassToTransform());
        }
        if (!i.isCacheable()) {
            nonCacheable.add(i.getClassToTransform());
        }
        classReaderOptions.merge(i.getClassToTransform(), i.getClassReaderOptions(), // class reader options are bit flags (see org.objectweb.asm.ClassReader)
        (oldValue, newValue) -> oldValue | newValue);
    }
    QuarkusClassLoader cl = (QuarkusClassLoader) Thread.currentThread().getContextClassLoader();
    Map<String, Path> transformedToArchive = new ConcurrentHashMap<>();
    // now copy all the contents to the runner jar
    // we also record if any additional archives needed transformation
    // when we copy these archives we will remove the problematic classes
    final ExecutorService executorPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
    final ConcurrentLinkedDeque<Future<TransformedClassesBuildItem.TransformedClass>> transformed = new ConcurrentLinkedDeque<>();
    final Map<Path, Set<TransformedClassesBuildItem.TransformedClass>> transformedClassesByJar = new HashMap<>();
    ClassLoader transformCl = Thread.currentThread().getContextClassLoader();
    lastTransformers = new BiFunction<String, byte[], byte[]>() {

        @Override
        public byte[] apply(String className, byte[] originalBytes) {
            List<BytecodeTransformerBuildItem> classTransformers = bytecodeTransformers.get(className);
            if (classTransformers == null) {
                return originalBytes;
            }
            boolean continueOnFailure = classTransformers.stream().filter(a -> !a.isContinueOnFailure()).findAny().isEmpty();
            List<BiFunction<String, ClassVisitor, ClassVisitor>> visitors = classTransformers.stream().map(BytecodeTransformerBuildItem::getVisitorFunction).filter(Objects::nonNull).collect(Collectors.toList());
            List<BiFunction<String, byte[], byte[]>> preVisitFunctions = classTransformers.stream().map(BytecodeTransformerBuildItem::getInputTransformer).filter(Objects::nonNull).collect(Collectors.toList());
            ClassLoader old = Thread.currentThread().getContextClassLoader();
            try {
                Thread.currentThread().setContextClassLoader(transformCl);
                String classFileName = className.replace('.', '/') + ".class";
                List<ClassPathElement> archives = cl.getElementsWithResource(classFileName);
                if (!archives.isEmpty()) {
                    ClassPathElement classPathElement = archives.get(0);
                    byte[] classData = classPathElement.getResource(classFileName).getData();
                    Set<String> constValues = constScanning.get(className);
                    if (constValues != null && !noConstScanning.contains(className)) {
                        if (!ConstPoolScanner.constPoolEntryPresent(classData, constValues)) {
                            return originalBytes;
                        }
                    }
                    byte[] data = transformClass(className, visitors, classData, preVisitFunctions, classReaderOptions.getOrDefault(className, 0));
                    TransformedClassesBuildItem.TransformedClass transformedClass = new TransformedClassesBuildItem.TransformedClass(className, data, classFileName, eager.contains(className));
                    return transformedClass.getData();
                } else {
                    return originalBytes;
                }
            } catch (Throwable e) {
                if (continueOnFailure) {
                    if (log.isDebugEnabled()) {
                        log.errorf(e, "Failed to transform %s", className);
                    } else {
                        log.errorf("Failed to transform %s", className);
                    }
                    return originalBytes;
                } else {
                    throw e;
                }
            } finally {
                Thread.currentThread().setContextClassLoader(old);
            }
        }
    };
    try {
        for (Map.Entry<String, List<BytecodeTransformerBuildItem>> entry : bytecodeTransformers.entrySet()) {
            String className = entry.getKey();
            boolean cacheable = !nonCacheable.contains(className);
            if (cacheable && transformedClassesCache.containsKey(className)) {
                if (liveReloadBuildItem.getChangeInformation() != null) {
                    if (!liveReloadBuildItem.getChangeInformation().getChangedClasses().contains(className)) {
                        // we can use the cached transformation
                        handleTransformedClass(transformedToArchive, transformedClassesByJar, transformedClassesCache.get(className));
                        continue;
                    }
                }
            }
            String classFileName = className.replace('.', '/') + ".class";
            List<ClassPathElement> archives = cl.getElementsWithResource(classFileName);
            if (!archives.isEmpty()) {
                ClassPathElement classPathElement = archives.get(0);
                Path jar = classPathElement.getRoot();
                if (jar == null) {
                    log.warnf("Cannot transform %s as its containing application archive could not be found.", entry.getKey());
                    continue;
                }
                boolean continueOnFailure = entry.getValue().stream().filter(a -> !a.isContinueOnFailure()).findAny().isEmpty();
                List<BiFunction<String, ClassVisitor, ClassVisitor>> visitors = entry.getValue().stream().map(BytecodeTransformerBuildItem::getVisitorFunction).filter(Objects::nonNull).collect(Collectors.toList());
                List<BiFunction<String, byte[], byte[]>> preVisitFunctions = entry.getValue().stream().map(BytecodeTransformerBuildItem::getInputTransformer).filter(Objects::nonNull).collect(Collectors.toList());
                transformedToArchive.put(classFileName, jar);
                transformed.add(executorPool.submit(new Callable<TransformedClassesBuildItem.TransformedClass>() {

                    @Override
                    public TransformedClassesBuildItem.TransformedClass call() throws Exception {
                        ClassLoader old = Thread.currentThread().getContextClassLoader();
                        try {
                            byte[] classData = classPathElement.getResource(classFileName).getData();
                            Thread.currentThread().setContextClassLoader(transformCl);
                            Set<String> constValues = constScanning.get(className);
                            if (constValues != null && !noConstScanning.contains(className)) {
                                if (!ConstPoolScanner.constPoolEntryPresent(classData, constValues)) {
                                    return null;
                                }
                            }
                            byte[] data = transformClass(className, visitors, classData, preVisitFunctions, classReaderOptions.getOrDefault(className, 0));
                            TransformedClassesBuildItem.TransformedClass transformedClass = new TransformedClassesBuildItem.TransformedClass(className, data, classFileName, eager.contains(className));
                            if (cacheable && launchModeBuildItem.getLaunchMode() == LaunchMode.DEVELOPMENT && classData != null) {
                                transformedClassesCache.put(className, transformedClass);
                            }
                            return transformedClass;
                        } catch (Throwable e) {
                            if (continueOnFailure) {
                                if (log.isDebugEnabled()) {
                                    log.errorf(e, "Failed to transform %s", className);
                                } else {
                                    log.errorf("Failed to transform %s", className);
                                }
                                return null;
                            } else {
                                throw e;
                            }
                        } finally {
                            Thread.currentThread().setContextClassLoader(old);
                        }
                    }
                }));
            } else {
                log.warnf("Cannot transform %s as its containing application archive could not be found.", entry.getKey());
            }
        }
    } finally {
        executorPool.shutdown();
    }
    handleRemovedResources(classLoadingConfig, curateOutcomeBuildItem, transformedClassesByJar, removedResourceBuildItems);
    if (!transformed.isEmpty()) {
        for (Future<TransformedClassesBuildItem.TransformedClass> i : transformed) {
            final TransformedClassesBuildItem.TransformedClass res = i.get();
            if (res != null) {
                handleTransformedClass(transformedToArchive, transformedClassesByJar, res);
            }
        }
    }
    if (packageConfig.writeTransformedBytecodeToBuildOutput && (launchMode.getLaunchMode() == LaunchMode.NORMAL)) {
        for (Path path : archiveRoot.getRootDirectories()) {
            copyTransformedClasses(path, transformedClassesByJar.get(path));
        }
    }
    return new TransformedClassesBuildItem(transformedClassesByJar);
}
Also used : TransformedClassesBuildItem(io.quarkus.deployment.builditem.TransformedClassesBuildItem) QuarkusClassWriter(io.quarkus.deployment.QuarkusClassWriter) BiFunction(java.util.function.BiFunction) Future(java.util.concurrent.Future) ArchiveRootBuildItem(io.quarkus.deployment.builditem.ArchiveRootBuildItem) Map(java.util.Map) QuarkusClassVisitor(io.quarkus.deployment.QuarkusClassVisitor) Path(java.nio.file.Path) ClassVisitor(org.objectweb.asm.ClassVisitor) Collection(java.util.Collection) StandardOpenOption(java.nio.file.StandardOpenOption) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) BootstrapDebug(io.quarkus.bootstrap.BootstrapDebug) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader) Collectors(java.util.stream.Collectors) Executors(java.util.concurrent.Executors) RemovedResourceBuildItem(io.quarkus.deployment.builditem.RemovedResourceBuildItem) PackageConfig(io.quarkus.deployment.pkg.PackageConfig) Objects(java.util.Objects) List(java.util.List) ApplicationModel(io.quarkus.bootstrap.model.ApplicationModel) ClassReader(org.objectweb.asm.ClassReader) GACT(io.quarkus.maven.dependency.GACT) ConstPoolScanner(io.quarkus.deployment.index.ConstPoolScanner) ResolvedDependency(io.quarkus.maven.dependency.ResolvedDependency) ClassWriter(org.objectweb.asm.ClassWriter) Logger(org.jboss.logging.Logger) LaunchMode(io.quarkus.runtime.LaunchMode) HashMap(java.util.HashMap) Callable(java.util.concurrent.Callable) CurateOutcomeBuildItem(io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) BuildStep(io.quarkus.deployment.annotations.BuildStep) ArtifactKey(io.quarkus.maven.dependency.ArtifactKey) ClassLoadingConfig(io.quarkus.deployment.configuration.ClassLoadingConfig) ExecutorService(java.util.concurrent.ExecutorService) ClassPathElement(io.quarkus.bootstrap.classloading.ClassPathElement) ApplicationArchivesBuildItem(io.quarkus.deployment.builditem.ApplicationArchivesBuildItem) Files(java.nio.file.Files) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) File(java.io.File) ConcurrentLinkedDeque(java.util.concurrent.ConcurrentLinkedDeque) ExecutionException(java.util.concurrent.ExecutionException) LaunchModeBuildItem(io.quarkus.deployment.builditem.LaunchModeBuildItem) BytecodeTransformerBuildItem(io.quarkus.deployment.builditem.BytecodeTransformerBuildItem) Collections(java.util.Collections) LiveReloadBuildItem(io.quarkus.deployment.builditem.LiveReloadBuildItem) Set(java.util.Set) HashSet(java.util.HashSet) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) QuarkusClassVisitor(io.quarkus.deployment.QuarkusClassVisitor) ClassVisitor(org.objectweb.asm.ClassVisitor) ClassPathElement(io.quarkus.bootstrap.classloading.ClassPathElement) Callable(java.util.concurrent.Callable) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader) List(java.util.List) ArrayList(java.util.ArrayList) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) BytecodeTransformerBuildItem(io.quarkus.deployment.builditem.BytecodeTransformerBuildItem) HashSet(java.util.HashSet) Path(java.nio.file.Path) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader) ConcurrentLinkedDeque(java.util.concurrent.ConcurrentLinkedDeque) TransformedClassesBuildItem(io.quarkus.deployment.builditem.TransformedClassesBuildItem) BiFunction(java.util.function.BiFunction) ExecutorService(java.util.concurrent.ExecutorService) Objects(java.util.Objects) Future(java.util.concurrent.Future) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) BuildStep(io.quarkus.deployment.annotations.BuildStep)

Example 4 with TransformedClassesBuildItem

use of io.quarkus.deployment.builditem.TransformedClassesBuildItem in project quarkus by quarkusio.

the class JarResultBuildStep method copyCommonContent.

private void copyCommonContent(FileSystem runnerZipFs, Map<String, List<byte[]>> concatenatedEntries, ApplicationArchivesBuildItem appArchives, TransformedClassesBuildItem transformedClassesBuildItem, List<GeneratedClassBuildItem> generatedClasses, List<GeneratedResourceBuildItem> generatedResources, Map<String, String> seen, Predicate<String> ignoredEntriesPredicate) throws IOException {
    // }
    for (Set<TransformedClassesBuildItem.TransformedClass> transformed : transformedClassesBuildItem.getTransformedClassesByJar().values()) {
        for (TransformedClassesBuildItem.TransformedClass i : transformed) {
            if (i.getData() != null) {
                Path target = runnerZipFs.getPath(i.getFileName());
                handleParent(runnerZipFs, i.getFileName(), seen);
                try (final OutputStream out = wrapForJDK8232879(Files.newOutputStream(target))) {
                    out.write(i.getData());
                }
                seen.put(i.getFileName(), "Current Application");
            }
        }
    }
    for (GeneratedClassBuildItem i : generatedClasses) {
        String fileName = i.getName().replace('.', '/') + ".class";
        seen.put(fileName, "Current Application");
        Path target = runnerZipFs.getPath(fileName);
        handleParent(runnerZipFs, fileName, seen);
        if (Files.exists(target)) {
            continue;
        }
        try (final OutputStream os = wrapForJDK8232879(Files.newOutputStream(target))) {
            os.write(i.getClassData());
        }
    }
    for (GeneratedResourceBuildItem i : generatedResources) {
        if (ignoredEntriesPredicate.test(i.getName())) {
            continue;
        }
        Path target = runnerZipFs.getPath(i.getName());
        handleParent(runnerZipFs, i.getName(), seen);
        if (Files.exists(target)) {
            continue;
        }
        if (i.getName().startsWith("META-INF/services/")) {
            concatenatedEntries.computeIfAbsent(i.getName(), (u) -> new ArrayList<>()).add(i.getClassData());
        } else {
            try (final OutputStream os = wrapForJDK8232879(Files.newOutputStream(target))) {
                os.write(i.getClassData());
            }
        }
    }
    copyFiles(appArchives.getRootArchive(), runnerZipFs, concatenatedEntries, ignoredEntriesPredicate);
    for (Map.Entry<String, List<byte[]>> entry : concatenatedEntries.entrySet()) {
        try (final OutputStream os = wrapForJDK8232879(Files.newOutputStream(runnerZipFs.getPath(entry.getKey())))) {
            // TODO: Handle merging of XMLs
            for (byte[] i : entry.getValue()) {
                os.write(i);
                os.write('\n');
            }
        }
    }
}
Also used : Path(java.nio.file.Path) Manifest(java.util.jar.Manifest) TransformedClassesBuildItem(io.quarkus.deployment.builditem.TransformedClassesBuildItem) Arrays(java.util.Arrays) BufferedInputStream(java.io.BufferedInputStream) Enumeration(java.util.Enumeration) URL(java.net.URL) UberJarIgnoredResourceBuildItem(io.quarkus.deployment.pkg.builditem.UberJarIgnoredResourceBuildItem) BooleanSupplier(java.util.function.BooleanSupplier) QuarkusBuildCloseablesBuildItem(io.quarkus.deployment.builditem.QuarkusBuildCloseablesBuildItem) Map(java.util.Map) ZipFile(java.util.zip.ZipFile) Path(java.nio.file.Path) ZipEntry(java.util.zip.ZipEntry) EnumSet(java.util.EnumSet) PathVisit(io.quarkus.paths.PathVisit) SimpleFileVisitor(java.nio.file.SimpleFileVisitor) ZipUtils(io.quarkus.fs.util.ZipUtils) Predicate(java.util.function.Predicate) JarBuildItem(io.quarkus.deployment.pkg.builditem.JarBuildItem) Collection(java.util.Collection) StandardOpenOption(java.nio.file.StandardOpenOption) MutableJarApplicationModel(io.quarkus.bootstrap.model.MutableJarApplicationModel) SerializedApplication(io.quarkus.bootstrap.runner.SerializedApplication) Set(java.util.Set) PathVisitor(io.quarkus.paths.PathVisitor) FileSystem(java.nio.file.FileSystem) Attributes(java.util.jar.Attributes) Collectors(java.util.stream.Collectors) AdditionalApplicationArchiveBuildItem(io.quarkus.deployment.builditem.AdditionalApplicationArchiveBuildItem) StandardCharsets(java.nio.charset.StandardCharsets) PackageConfig(io.quarkus.deployment.pkg.PackageConfig) UncheckedIOException(java.io.UncheckedIOException) FileUtil(io.quarkus.deployment.util.FileUtil) FileVisitResult(java.nio.file.FileVisitResult) LegacyJarRequiredBuildItem(io.quarkus.deployment.pkg.builditem.LegacyJarRequiredBuildItem) NativeImageSourceJarBuildItem(io.quarkus.deployment.pkg.builditem.NativeImageSourceJarBuildItem) List(java.util.List) Stream(java.util.stream.Stream) GACT(io.quarkus.maven.dependency.GACT) ResolvedDependency(io.quarkus.maven.dependency.ResolvedDependency) Optional(java.util.Optional) GeneratedNativeImageClassBuildItem(io.quarkus.deployment.builditem.GeneratedNativeImageClassBuildItem) ZipOutputStream(java.util.zip.ZipOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) QuarkusEntryPoint(io.quarkus.bootstrap.runner.QuarkusEntryPoint) Logger(org.jboss.logging.Logger) HashMap(java.util.HashMap) CurateOutcomeBuildItem(io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem) StandardCopyOption(java.nio.file.StandardCopyOption) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) BiPredicate(java.util.function.BiPredicate) BuildStep(io.quarkus.deployment.annotations.BuildStep) IoUtils(io.quarkus.bootstrap.util.IoUtils) ArtifactKey(io.quarkus.maven.dependency.ArtifactKey) ClassLoadingConfig(io.quarkus.deployment.configuration.ClassLoadingConfig) Dependency(io.quarkus.maven.dependency.Dependency) ObjectOutputStream(java.io.ObjectOutputStream) BuildSystemTargetBuildItem(io.quarkus.deployment.pkg.builditem.BuildSystemTargetBuildItem) OutputStream(java.io.OutputStream) GeneratedResourceBuildItem(io.quarkus.deployment.builditem.GeneratedResourceBuildItem) ApplicationArchivesBuildItem(io.quarkus.deployment.builditem.ApplicationArchivesBuildItem) UberJarRequiredBuildItem(io.quarkus.deployment.pkg.builditem.UberJarRequiredBuildItem) Files(java.nio.file.Files) BufferedWriter(java.io.BufferedWriter) SystemUtils(org.apache.commons.lang3.SystemUtils) FileOutputStream(java.io.FileOutputStream) ArtifactResultBuildItem(io.quarkus.deployment.pkg.builditem.ArtifactResultBuildItem) IOException(java.io.IOException) FileAlreadyExistsException(java.nio.file.FileAlreadyExistsException) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes) Consumer(java.util.function.Consumer) ApplicationArchive(io.quarkus.deployment.ApplicationArchive) GeneratedClassBuildItem(io.quarkus.deployment.builditem.GeneratedClassBuildItem) FileVisitOption(java.nio.file.FileVisitOption) Paths(java.nio.file.Paths) OutputTargetBuildItem(io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem) ZipUtils.wrapForJDK8232879(io.quarkus.fs.util.ZipUtils.wrapForJDK8232879) ApplicationInfoBuildItem(io.quarkus.deployment.builditem.ApplicationInfoBuildItem) AppCDSRequestedBuildItem(io.quarkus.deployment.pkg.builditem.AppCDSRequestedBuildItem) UberJarMergedResourceBuildItem(io.quarkus.deployment.pkg.builditem.UberJarMergedResourceBuildItem) Comparator(java.util.Comparator) Collections(java.util.Collections) MainClassBuildItem(io.quarkus.deployment.builditem.MainClassBuildItem) InputStream(java.io.InputStream) GeneratedResourceBuildItem(io.quarkus.deployment.builditem.GeneratedResourceBuildItem) ZipOutputStream(java.util.zip.ZipOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ObjectOutputStream(java.io.ObjectOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) ArrayList(java.util.ArrayList) TransformedClassesBuildItem(io.quarkus.deployment.builditem.TransformedClassesBuildItem) GeneratedClassBuildItem(io.quarkus.deployment.builditem.GeneratedClassBuildItem) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) HashMap(java.util.HashMap)

Example 5 with TransformedClassesBuildItem

use of io.quarkus.deployment.builditem.TransformedClassesBuildItem in project quarkus by quarkusio.

the class JarResultBuildStep method copyDependency.

private void copyDependency(Set<ArtifactKey> parentFirstArtifacts, OutputTargetBuildItem outputTargetBuildItem, Map<ArtifactKey, List<Path>> runtimeArtifacts, Path libDir, Path baseLib, List<Path> jars, boolean allowParentFirst, StringBuilder classPath, ResolvedDependency appDep, TransformedClassesBuildItem transformedClasses, Set<ArtifactKey> removedDeps) throws IOException {
    // and are not part of the optional dependencies to include
    if (!includeAppDep(appDep, outputTargetBuildItem.getIncludedOptionalDependencies(), removedDeps)) {
        return;
    }
    if (runtimeArtifacts.containsKey(appDep.getKey())) {
        return;
    }
    for (Path resolvedDep : appDep.getResolvedPaths()) {
        final String fileName = appDep.getGroupId() + "." + resolvedDep.getFileName();
        final Path targetPath;
        if (allowParentFirst && parentFirstArtifacts.contains(appDep.getKey())) {
            targetPath = baseLib.resolve(fileName);
            classPath.append(" ").append(LIB).append("/").append(BOOT_LIB).append("/").append(fileName);
        } else {
            targetPath = libDir.resolve(fileName);
            jars.add(targetPath);
        }
        runtimeArtifacts.computeIfAbsent(appDep.getKey(), (s) -> new ArrayList<>(1)).add(targetPath);
        if (Files.isDirectory(resolvedDep)) {
            // This case can happen when we are building a jar from inside the Quarkus repository
            // and Quarkus Bootstrap's localProjectDiscovery has been set to true. In such a case
            // the non-jar dependencies are the Quarkus dependencies picked up on the file system
            packageClasses(resolvedDep, targetPath);
        } else {
            Set<TransformedClassesBuildItem.TransformedClass> transformedFromThisArchive = transformedClasses.getTransformedClassesByJar().get(resolvedDep);
            Set<String> removedFromThisArchive = new HashSet<>();
            if (transformedFromThisArchive != null) {
                for (TransformedClassesBuildItem.TransformedClass i : transformedFromThisArchive) {
                    if (i.getData() == null) {
                        removedFromThisArchive.add(i.getFileName());
                    }
                }
            }
            if (removedFromThisArchive.isEmpty()) {
                Files.copy(resolvedDep, targetPath, StandardCopyOption.REPLACE_EXISTING);
            } else {
                // we have removed classes, we need to handle them correctly
                filterZipFile(resolvedDep, targetPath, removedFromThisArchive);
            }
        }
    }
}
Also used : Path(java.nio.file.Path) Manifest(java.util.jar.Manifest) TransformedClassesBuildItem(io.quarkus.deployment.builditem.TransformedClassesBuildItem) Arrays(java.util.Arrays) BufferedInputStream(java.io.BufferedInputStream) Enumeration(java.util.Enumeration) URL(java.net.URL) UberJarIgnoredResourceBuildItem(io.quarkus.deployment.pkg.builditem.UberJarIgnoredResourceBuildItem) BooleanSupplier(java.util.function.BooleanSupplier) QuarkusBuildCloseablesBuildItem(io.quarkus.deployment.builditem.QuarkusBuildCloseablesBuildItem) Map(java.util.Map) ZipFile(java.util.zip.ZipFile) Path(java.nio.file.Path) ZipEntry(java.util.zip.ZipEntry) EnumSet(java.util.EnumSet) PathVisit(io.quarkus.paths.PathVisit) SimpleFileVisitor(java.nio.file.SimpleFileVisitor) ZipUtils(io.quarkus.fs.util.ZipUtils) Predicate(java.util.function.Predicate) JarBuildItem(io.quarkus.deployment.pkg.builditem.JarBuildItem) Collection(java.util.Collection) StandardOpenOption(java.nio.file.StandardOpenOption) MutableJarApplicationModel(io.quarkus.bootstrap.model.MutableJarApplicationModel) SerializedApplication(io.quarkus.bootstrap.runner.SerializedApplication) Set(java.util.Set) PathVisitor(io.quarkus.paths.PathVisitor) FileSystem(java.nio.file.FileSystem) Attributes(java.util.jar.Attributes) Collectors(java.util.stream.Collectors) AdditionalApplicationArchiveBuildItem(io.quarkus.deployment.builditem.AdditionalApplicationArchiveBuildItem) StandardCharsets(java.nio.charset.StandardCharsets) PackageConfig(io.quarkus.deployment.pkg.PackageConfig) UncheckedIOException(java.io.UncheckedIOException) FileUtil(io.quarkus.deployment.util.FileUtil) FileVisitResult(java.nio.file.FileVisitResult) LegacyJarRequiredBuildItem(io.quarkus.deployment.pkg.builditem.LegacyJarRequiredBuildItem) NativeImageSourceJarBuildItem(io.quarkus.deployment.pkg.builditem.NativeImageSourceJarBuildItem) List(java.util.List) Stream(java.util.stream.Stream) GACT(io.quarkus.maven.dependency.GACT) ResolvedDependency(io.quarkus.maven.dependency.ResolvedDependency) Optional(java.util.Optional) GeneratedNativeImageClassBuildItem(io.quarkus.deployment.builditem.GeneratedNativeImageClassBuildItem) ZipOutputStream(java.util.zip.ZipOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) QuarkusEntryPoint(io.quarkus.bootstrap.runner.QuarkusEntryPoint) Logger(org.jboss.logging.Logger) HashMap(java.util.HashMap) CurateOutcomeBuildItem(io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem) StandardCopyOption(java.nio.file.StandardCopyOption) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) BiPredicate(java.util.function.BiPredicate) BuildStep(io.quarkus.deployment.annotations.BuildStep) IoUtils(io.quarkus.bootstrap.util.IoUtils) ArtifactKey(io.quarkus.maven.dependency.ArtifactKey) ClassLoadingConfig(io.quarkus.deployment.configuration.ClassLoadingConfig) Dependency(io.quarkus.maven.dependency.Dependency) ObjectOutputStream(java.io.ObjectOutputStream) BuildSystemTargetBuildItem(io.quarkus.deployment.pkg.builditem.BuildSystemTargetBuildItem) OutputStream(java.io.OutputStream) GeneratedResourceBuildItem(io.quarkus.deployment.builditem.GeneratedResourceBuildItem) ApplicationArchivesBuildItem(io.quarkus.deployment.builditem.ApplicationArchivesBuildItem) UberJarRequiredBuildItem(io.quarkus.deployment.pkg.builditem.UberJarRequiredBuildItem) Files(java.nio.file.Files) BufferedWriter(java.io.BufferedWriter) SystemUtils(org.apache.commons.lang3.SystemUtils) FileOutputStream(java.io.FileOutputStream) ArtifactResultBuildItem(io.quarkus.deployment.pkg.builditem.ArtifactResultBuildItem) IOException(java.io.IOException) FileAlreadyExistsException(java.nio.file.FileAlreadyExistsException) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes) Consumer(java.util.function.Consumer) ApplicationArchive(io.quarkus.deployment.ApplicationArchive) GeneratedClassBuildItem(io.quarkus.deployment.builditem.GeneratedClassBuildItem) FileVisitOption(java.nio.file.FileVisitOption) Paths(java.nio.file.Paths) OutputTargetBuildItem(io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem) ZipUtils.wrapForJDK8232879(io.quarkus.fs.util.ZipUtils.wrapForJDK8232879) ApplicationInfoBuildItem(io.quarkus.deployment.builditem.ApplicationInfoBuildItem) AppCDSRequestedBuildItem(io.quarkus.deployment.pkg.builditem.AppCDSRequestedBuildItem) UberJarMergedResourceBuildItem(io.quarkus.deployment.pkg.builditem.UberJarMergedResourceBuildItem) Comparator(java.util.Comparator) Collections(java.util.Collections) MainClassBuildItem(io.quarkus.deployment.builditem.MainClassBuildItem) InputStream(java.io.InputStream) TransformedClassesBuildItem(io.quarkus.deployment.builditem.TransformedClassesBuildItem) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet)

Aggregations

TransformedClassesBuildItem (io.quarkus.deployment.builditem.TransformedClassesBuildItem)6 Path (java.nio.file.Path)5 HashMap (java.util.HashMap)5 GeneratedClassBuildItem (io.quarkus.deployment.builditem.GeneratedClassBuildItem)4 ArtifactKey (io.quarkus.maven.dependency.ArtifactKey)4 ResolvedDependency (io.quarkus.maven.dependency.ResolvedDependency)4 FileOutputStream (java.io.FileOutputStream)4 ArrayList (java.util.ArrayList)4 List (java.util.List)4 Map (java.util.Map)4 MutableJarApplicationModel (io.quarkus.bootstrap.model.MutableJarApplicationModel)3 QuarkusEntryPoint (io.quarkus.bootstrap.runner.QuarkusEntryPoint)3 BuildStep (io.quarkus.deployment.annotations.BuildStep)3 AdditionalApplicationArchiveBuildItem (io.quarkus.deployment.builditem.AdditionalApplicationArchiveBuildItem)3 ApplicationArchivesBuildItem (io.quarkus.deployment.builditem.ApplicationArchivesBuildItem)3 GeneratedResourceBuildItem (io.quarkus.deployment.builditem.GeneratedResourceBuildItem)3 ClassLoadingConfig (io.quarkus.deployment.configuration.ClassLoadingConfig)3 PackageConfig (io.quarkus.deployment.pkg.PackageConfig)3 CurateOutcomeBuildItem (io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem)3 JarBuildItem (io.quarkus.deployment.pkg.builditem.JarBuildItem)3