Search in sources :

Example 1 with StartupAction

use of io.quarkus.bootstrap.app.StartupAction in project quarkus by quarkusio.

the class QuarkusDeployableContainer method deploy.

@SuppressWarnings("rawtypes")
@Override
public ProtocolMetaData deploy(Archive<?> archive) throws DeploymentException {
    old = Thread.currentThread().getContextClassLoader();
    if (testClass.get() == null) {
        throw new IllegalStateException("Test class not available");
    }
    Class testJavaClass = testClass.get().getJavaClass();
    // some TCK tests embed random libraries such as old versions of Jackson databind
    // this breaks quarkus, so we just skip them
    boolean skipLibraries = Boolean.getBoolean("io.quarkus.arquillian.skip-libraries");
    try {
        // Export the test archive
        Path tmpLocation = Files.createTempDirectory("quarkus-arquillian-test");
        deploymentLocation.set(tmpLocation);
        archive.as(ExplodedExporter.class).exportExplodedInto(tmpLocation.toFile());
        Path appLocation;
        Set<Path> libraries = new HashSet<>();
        if (archive instanceof WebArchive) {
            // Quarkus does not support the WAR layout and so adapt the layout (similarly to quarkus-war-launcher)
            appLocation = tmpLocation.resolve("app").toAbsolutePath();
            // WEB-INF/lib -> lib/
            if (!skipLibraries) {
                if (Files.exists(tmpLocation.resolve("WEB-INF/lib"))) {
                    Files.move(tmpLocation.resolve("WEB-INF/lib"), tmpLocation.resolve("lib"));
                }
            }
            // WEB-INF/classes -> archive/
            if (Files.exists(tmpLocation.resolve("WEB-INF/classes"))) {
                Files.move(tmpLocation.resolve("WEB-INF/classes"), appLocation);
            } else {
                Files.createDirectory(appLocation);
            }
            // META-INF -> archive/META-INF/
            if (Files.exists(tmpLocation.resolve("META-INF"))) {
                if (Files.exists(appLocation.resolve("META-INF"))) {
                    // Target directory not empty.
                    try (Stream<Path> fileTreeElements = Files.walk(tmpLocation.resolve("META-INF"), 2)) {
                        fileTreeElements.forEach(p -> {
                            try {
                                Files.createFile(p);
                            } catch (FileAlreadyExistsException faee) {
                            // Do Nothing
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        });
                    }
                } else {
                    Files.move(tmpLocation.resolve("META-INF"), appLocation.resolve("META-INF"));
                }
            }
            // WEB-INF -> archive/WEB-INF
            if (Files.exists(tmpLocation.resolve("WEB-INF"))) {
                Files.move(tmpLocation.resolve("WEB-INF"), appLocation.resolve("WEB-INF"));
            }
            // Collect all libraries
            if (Files.exists(tmpLocation.resolve("lib"))) {
                try (Stream<Path> libs = Files.walk(tmpLocation.resolve("lib"), 1)) {
                    libs.forEach((i) -> {
                        if (i.getFileName().toString().endsWith(".jar")) {
                            libraries.add(i);
                        }
                    });
                }
            }
        } else {
            appLocation = tmpLocation;
        }
        List<Consumer<BuildChainBuilder>> customizers = new ArrayList<>();
        // Test class is a bean
        customizers.add(new Consumer<BuildChainBuilder>() {

            @Override
            public void accept(BuildChainBuilder buildChainBuilder) {
                buildChainBuilder.addBuildStep(new BuildStep() {

                    @Override
                    public void execute(BuildContext context) {
                        context.produce(AdditionalBeanBuildItem.unremovableOf(testJavaClass));
                    }
                }).produces(AdditionalBeanBuildItem.class).build();
            }
        });
        QuarkusBootstrap.Builder bootstrapBuilder = QuarkusBootstrap.builder().setApplicationRoot(appLocation).setProjectRoot(appLocation).setIsolateDeployment(false).setFlatClassPath(true).setMode(QuarkusBootstrap.Mode.TEST);
        for (Path i : libraries) {
            bootstrapBuilder.addAdditionalApplicationArchive(new AdditionalDependency(i, false, true));
        }
        // Path testLocation = PathTestHelper.getTestClassesLocation(testJavaClass);
        // bootstrapBuilder.setProjectRoot(PathTestHelper.getTestClassesLocation(testJavaClass));
        CuratedApplication curatedApplication = bootstrapBuilder.build().bootstrap();
        AugmentAction augmentAction = new AugmentActionImpl(curatedApplication, customizers);
        StartupAction app = augmentAction.createInitialRuntimeApplication();
        RunningQuarkusApplication runningQuarkusApplication = app.run();
        appClassloader.set(runningQuarkusApplication.getClassLoader());
        runningApp.set(runningQuarkusApplication);
        Thread.currentThread().setContextClassLoader(runningQuarkusApplication.getClassLoader());
        // Instantiate the real test instance
        testInstance = TestInstantiator.instantiateTest(testJavaClass, runningQuarkusApplication.getClassLoader());
        // its pretty bogus
        if (Boolean.getBoolean("io.quarkus.arquillian.copy-fields")) {
            Class<?> dest = testInstance.getClass();
            Class<?> source = testClass.get().getJavaClass();
            while (source != Object.class) {
                for (Field f : source.getDeclaredFields()) {
                    try {
                        if (Modifier.isStatic(f.getModifiers()) && !Modifier.isFinal(f.getModifiers())) {
                            Field df = dest.getDeclaredField(f.getName());
                            df.setAccessible(true);
                            f.setAccessible(true);
                            df.set(null, f.get(null));
                        }
                    } catch (Exception e) {
                        LOGGER.error("Failed to copy static field", e);
                    }
                }
                source = source.getSuperclass();
                dest = dest.getSuperclass();
            }
        }
    } catch (Throwable t) {
        // clone the exception into the correct class loader
        Throwable nt;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try (ObjectOutputStream a = new ObjectOutputStream(out)) {
            a.writeObject(t);
            a.close();
            nt = (Throwable) new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())).readObject();
        } catch (Exception e) {
            throw new DeploymentException("Unable to start the runtime runner", t);
        }
        throw new DeploymentException("Unable to start the runtime runner", nt);
    } finally {
        Thread.currentThread().setContextClassLoader(old);
    }
    ProtocolMetaData metadata = new ProtocolMetaData();
    // TODO: fix this
    String testUri = TestHTTPResourceManager.getUri(runningApp.get());
    System.setProperty("test.url", testUri);
    URI uri = URI.create(testUri);
    HTTPContext httpContext = new HTTPContext(uri.getHost(), uri.getPort());
    // This is to work around https://github.com/arquillian/arquillian-core/issues/216
    httpContext.add(new Servlet("dummy", "/"));
    metadata.addContext(httpContext);
    return metadata;
}
Also used : FileAlreadyExistsException(java.nio.file.FileAlreadyExistsException) ArrayList(java.util.ArrayList) BuildStep(io.quarkus.builder.BuildStep) ObjectOutputStream(java.io.ObjectOutputStream) URI(java.net.URI) Field(java.lang.reflect.Field) Consumer(java.util.function.Consumer) Servlet(org.jboss.arquillian.container.spi.client.protocol.metadata.Servlet) AdditionalDependency(io.quarkus.bootstrap.app.AdditionalDependency) ProtocolMetaData(org.jboss.arquillian.container.spi.client.protocol.metadata.ProtocolMetaData) ExplodedExporter(org.jboss.shrinkwrap.api.exporter.ExplodedExporter) HashSet(java.util.HashSet) AugmentActionImpl(io.quarkus.runner.bootstrap.AugmentActionImpl) Path(java.nio.file.Path) AugmentAction(io.quarkus.bootstrap.app.AugmentAction) StartupAction(io.quarkus.bootstrap.app.StartupAction) RunningQuarkusApplication(io.quarkus.bootstrap.app.RunningQuarkusApplication) WebArchive(org.jboss.shrinkwrap.api.spec.WebArchive) HTTPContext(org.jboss.arquillian.container.spi.client.protocol.metadata.HTTPContext) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) LifecycleException(org.jboss.arquillian.container.spi.client.container.LifecycleException) IOException(java.io.IOException) FileAlreadyExistsException(java.nio.file.FileAlreadyExistsException) DeploymentException(org.jboss.arquillian.container.spi.client.container.DeploymentException) BuildContext(io.quarkus.builder.BuildContext) BuildChainBuilder(io.quarkus.builder.BuildChainBuilder) CuratedApplication(io.quarkus.bootstrap.app.CuratedApplication) ByteArrayInputStream(java.io.ByteArrayInputStream) QuarkusBootstrap(io.quarkus.bootstrap.app.QuarkusBootstrap) TestClass(org.jboss.arquillian.test.spi.TestClass) DeploymentException(org.jboss.arquillian.container.spi.client.container.DeploymentException) ObjectInputStream(java.io.ObjectInputStream)

Example 2 with StartupAction

use of io.quarkus.bootstrap.app.StartupAction in project quarkus by quarkusio.

the class QuarkusTestExtension method doJavaStart.

private ExtensionState doJavaStart(ExtensionContext context, Class<? extends QuarkusTestProfile> profile) throws Throwable {
    TracingHandler.quarkusStarting();
    hangDetectionExecutor = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "Quarkus hang detection timer thread");
        }
    });
    String time = "10m";
    // config is not established yet
    // we can only read from system properties
    String sysPropString = System.getProperty(QUARKUS_TEST_HANG_DETECTION_TIMEOUT);
    if (sysPropString != null) {
        time = sysPropString;
    }
    hangTimeout = new DurationConverter().convert(time);
    hangTaskKey = hangDetectionExecutor.schedule(hangDetectionTask, hangTimeout.toMillis(), TimeUnit.MILLISECONDS);
    quarkusTestProfile = profile;
    Class<?> requiredTestClass = context.getRequiredTestClass();
    Closeable testResourceManager = null;
    try {
        final LinkedBlockingDeque<Runnable> shutdownTasks = new LinkedBlockingDeque<>();
        PrepareResult result = createAugmentor(context, profile, shutdownTasks);
        AugmentAction augmentAction = result.augmentAction;
        QuarkusTestProfile profileInstance = result.profileInstance;
        testHttpEndpointProviders = TestHttpEndpointProvider.load();
        StartupAction startupAction = augmentAction.createInitialRuntimeApplication();
        Thread.currentThread().setContextClassLoader(startupAction.getClassLoader());
        populateDeepCloneField(startupAction);
        // must be done after the TCCL has been set
        testResourceManager = (Closeable) startupAction.getClassLoader().loadClass(TestResourceManager.class.getName()).getConstructor(Class.class, Class.class, List.class, boolean.class, Map.class, Optional.class).newInstance(requiredTestClass, profile != null ? profile : null, getAdditionalTestResources(profileInstance, startupAction.getClassLoader()), profileInstance != null && profileInstance.disableGlobalTestResources(), startupAction.getDevServicesProperties(), Optional.empty());
        testResourceManager.getClass().getMethod("init", String.class).invoke(testResourceManager, profile != null ? profile.getName() : null);
        Map<String, String> properties = (Map<String, String>) testResourceManager.getClass().getMethod("start").invoke(testResourceManager);
        startupAction.overrideConfig(properties);
        hasPerTestResources = (boolean) testResourceManager.getClass().getMethod("hasPerTestResources").invoke(testResourceManager);
        populateCallbacks(startupAction.getClassLoader());
        populateTestMethodInvokers(startupAction.getClassLoader());
        if (profileInstance == null || !profileInstance.runMainMethod()) {
            runningQuarkusApplication = startupAction.run(profileInstance == null ? new String[0] : profileInstance.commandLineParameters());
        } else {
            Class<?> lifecycleManager = Class.forName(ApplicationLifecycleManager.class.getName(), true, startupAction.getClassLoader());
            lifecycleManager.getDeclaredMethod("setDefaultExitCodeHandler", Consumer.class).invoke(null, (Consumer<Integer>) integer -> {
            });
            runningQuarkusApplication = startupAction.runMainClass(profileInstance.commandLineParameters());
        }
        String patternString = runningQuarkusApplication.getConfigValue("quarkus.test.class-clone-pattern", String.class).orElse("java\\..*");
        clonePattern = Pattern.compile(patternString);
        TracingHandler.quarkusStarted();
        if (hangTaskKey != null) {
            hangTaskKey.cancel(false);
            hangTimeout = runningQuarkusApplication.getConfigValue(QUARKUS_TEST_HANG_DETECTION_TIMEOUT, Duration.class).orElse(Duration.of(10, ChronoUnit.MINUTES));
            hangTaskKey = hangDetectionExecutor.schedule(hangDetectionTask, hangTimeout.toMillis(), TimeUnit.MILLISECONDS);
        }
        ConfigProviderResolver.setInstance(new RunningAppConfigResolver(runningQuarkusApplication));
        RestorableSystemProperties restorableSystemProperties = RestorableSystemProperties.setProperties(Collections.singletonMap("test.url", TestHTTPResourceManager.getUri(runningQuarkusApplication)));
        Closeable tm = testResourceManager;
        Closeable shutdownTask = new Closeable() {

            @Override
            public void close() throws IOException {
                TracingHandler.quarkusStopping();
                try {
                    runningQuarkusApplication.close();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                } finally {
                    TracingHandler.quarkusStopped();
                    try {
                        while (!shutdownTasks.isEmpty()) {
                            shutdownTasks.pop().run();
                        }
                    } finally {
                        try {
                            tm.close();
                        } finally {
                            restorableSystemProperties.close();
                            GroovyCacheCleaner.clearGroovyCache();
                            shutdownHangDetection();
                        }
                    }
                    try {
                        TestClassIndexer.removeIndex(requiredTestClass);
                    } catch (Exception ignored) {
                    }
                }
            }
        };
        ExtensionState state = new ExtensionState(testResourceManager, shutdownTask);
        return state;
    } catch (Throwable e) {
        if (!InitialConfigurator.DELAYED_HANDLER.isActivated()) {
            activateLogging();
        }
        try {
            if (testResourceManager != null) {
                testResourceManager.close();
            }
        } catch (Exception ex) {
            e.addSuppressed(ex);
        }
        throw e;
    } finally {
        if (originalCl != null) {
            Thread.currentThread().setContextClassLoader(originalCl);
        }
    }
}
Also used : ApplicationLifecycleManager(io.quarkus.runtime.ApplicationLifecycleManager) RestAssuredURLManager(io.quarkus.test.common.RestAssuredURLManager) FieldInfo(org.jboss.jandex.FieldInfo) ApplicationLifecycleManager(io.quarkus.runtime.ApplicationLifecycleManager) ThreadInfo(java.lang.management.ThreadInfo) TestClassPredicateBuildItem(io.quarkus.deployment.builditem.TestClassPredicateBuildItem) Duration(java.time.Duration) Map(java.util.Map) AugmentAction(io.quarkus.bootstrap.app.AugmentAction) QuarkusTestAfterEachCallback(io.quarkus.test.junit.callback.QuarkusTestAfterEachCallback) InitialConfigurator(io.quarkus.bootstrap.logging.InitialConfigurator) Path(java.nio.file.Path) DurationConverter(io.quarkus.runtime.configuration.DurationConverter) TestAbortedException(org.opentest4j.TestAbortedException) TestHttpEndpointProvider(io.quarkus.runtime.test.TestHttpEndpointProvider) Set(java.util.Set) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader) Executors(java.util.concurrent.Executors) StartupAction(io.quarkus.bootstrap.app.StartupAction) InvocationTargetException(java.lang.reflect.InvocationTargetException) ReflectiveInvocationContext(org.junit.jupiter.api.extension.ReflectiveInvocationContext) BuildStep(io.quarkus.builder.BuildStep) TestClassBeanBuildItem(io.quarkus.deployment.builditem.TestClassBeanBuildItem) AnnotationInstance(org.jboss.jandex.AnnotationInstance) QuarkusTestMethodContext(io.quarkus.test.junit.callback.QuarkusTestMethodContext) PropertyTestUtil(io.quarkus.test.common.PropertyTestUtil) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ExtensionContext(org.junit.jupiter.api.extension.ExtensionContext) Constructor(java.lang.reflect.Constructor) Supplier(java.util.function.Supplier) Nested(org.junit.jupiter.api.Nested) RestorableSystemProperties(io.quarkus.test.common.RestorableSystemProperties) ArrayList(java.util.ArrayList) BuildChainBuilder(io.quarkus.builder.BuildChainBuilder) Parameter(java.lang.reflect.Parameter) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ManagementFactory(java.lang.management.ManagementFactory) IntegrationTestUtil.getAdditionalTestResources(io.quarkus.test.junit.IntegrationTestUtil.getAdditionalTestResources) ParameterResolutionException(org.junit.jupiter.api.extension.ParameterResolutionException) IOException(java.io.IOException) ParameterContext(org.junit.jupiter.api.extension.ParameterContext) ChronoUnit(java.time.temporal.ChronoUnit) BeforeAllCallback(org.junit.jupiter.api.extension.BeforeAllCallback) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) BeforeEachCallback(org.junit.jupiter.api.extension.BeforeEachCallback) TestResourceManager(io.quarkus.test.common.TestResourceManager) TestHTTPResourceManager(io.quarkus.test.common.http.TestHTTPResourceManager) QuarkusTestContext(io.quarkus.test.junit.callback.QuarkusTestContext) TestHTTPEndpoint(io.quarkus.test.common.http.TestHTTPEndpoint) ScheduledFuture(java.util.concurrent.ScheduledFuture) QuarkusTestBeforeEachCallback(io.quarkus.test.junit.callback.QuarkusTestBeforeEachCallback) QuarkusTestBeforeClassCallback(io.quarkus.test.junit.callback.QuarkusTestBeforeClassCallback) ClassInfo(org.jboss.jandex.ClassInfo) DeepClone(io.quarkus.test.junit.internal.DeepClone) ConfigProviderResolver(org.eclipse.microprofile.config.spi.ConfigProviderResolver) AfterEachCallback(org.junit.jupiter.api.extension.AfterEachCallback) Locale(java.util.Locale) AnnotationTarget(org.jboss.jandex.AnnotationTarget) ThreadFactory(java.util.concurrent.ThreadFactory) Method(java.lang.reflect.Method) GroovyCacheCleaner(io.quarkus.test.common.GroovyCacheCleaner) Predicate(java.util.function.Predicate) ServiceLoader(java.util.ServiceLoader) TestInfo(org.junit.jupiter.api.TestInfo) Objects(java.util.Objects) List(java.util.List) TestBuildChainCustomizerProducer(io.quarkus.test.junit.buildchain.TestBuildChainCustomizerProducer) BuildContext(io.quarkus.builder.BuildContext) Optional(java.util.Optional) Pattern(java.util.regex.Pattern) TestScopeManager(io.quarkus.test.common.TestScopeManager) PathTestHelper(io.quarkus.test.common.PathTestHelper) TestClassIndexer(io.quarkus.test.common.TestClassIndexer) RunningQuarkusApplication(io.quarkus.bootstrap.app.RunningQuarkusApplication) TestAnnotationBuildItem(io.quarkus.deployment.builditem.TestAnnotationBuildItem) Logger(org.jboss.logging.Logger) Type(org.jboss.jandex.Type) TracingHandler(io.quarkus.dev.testing.TracingHandler) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) LaunchMode(io.quarkus.runtime.LaunchMode) HashMap(java.util.HashMap) IntegrationTestUtil.activateLogging(io.quarkus.test.junit.IntegrationTestUtil.activateLogging) Function(java.util.function.Function) QuarkusTestAfterAllCallback(io.quarkus.test.junit.callback.QuarkusTestAfterAllCallback) QuarkusTestAfterConstructCallback(io.quarkus.test.junit.callback.QuarkusTestAfterConstructCallback) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) TestMethodInvoker(io.quarkus.test.TestMethodInvoker) ApplicationClassPredicateBuildItem(io.quarkus.deployment.builditem.ApplicationClassPredicateBuildItem) Index(org.jboss.jandex.Index) ClassPathElement(io.quarkus.bootstrap.classloading.ClassPathElement) InvocationInterceptor(org.junit.jupiter.api.extension.InvocationInterceptor) TestInstantiationException(org.junit.jupiter.api.extension.TestInstantiationException) SerializationWithXStreamFallbackDeepClone(io.quarkus.test.junit.internal.SerializationWithXStreamFallbackDeepClone) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) AbstractMap(java.util.AbstractMap) ConditionEvaluationResult(org.junit.jupiter.api.extension.ConditionEvaluationResult) ExecutionCondition(org.junit.jupiter.api.extension.ExecutionCondition) AfterAllCallback(org.junit.jupiter.api.extension.AfterAllCallback) ExceptionReporting(io.quarkus.dev.testing.ExceptionReporting) Closeable(java.io.Closeable) ProfileManager(io.quarkus.runtime.configuration.ProfileManager) Collections(java.util.Collections) ParameterResolver(org.junit.jupiter.api.extension.ParameterResolver) ThreadFactory(java.util.concurrent.ThreadFactory) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) Closeable(java.io.Closeable) Consumer(java.util.function.Consumer) DurationConverter(io.quarkus.runtime.configuration.DurationConverter) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) List(java.util.List) AugmentAction(io.quarkus.bootstrap.app.AugmentAction) StartupAction(io.quarkus.bootstrap.app.StartupAction) Optional(java.util.Optional) TestAbortedException(org.opentest4j.TestAbortedException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ParameterResolutionException(org.junit.jupiter.api.extension.ParameterResolutionException) IOException(java.io.IOException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) TestInstantiationException(org.junit.jupiter.api.extension.TestInstantiationException) RestorableSystemProperties(io.quarkus.test.common.RestorableSystemProperties) Map(java.util.Map) HashMap(java.util.HashMap) AbstractMap(java.util.AbstractMap) TestResourceManager(io.quarkus.test.common.TestResourceManager)

Example 3 with StartupAction

use of io.quarkus.bootstrap.app.StartupAction in project quarkus by quarkusio.

the class IsolatedDevModeMain method firstStart.

private synchronized void firstStart(QuarkusClassLoader deploymentClassLoader, List<CodeGenData> codeGens) {
    ClassLoader old = Thread.currentThread().getContextClassLoader();
    try {
        // ok, we have resolved all the deps
        try {
            StartupAction start = augmentAction.createInitialRuntimeApplication();
            // this is a bit yuck, but we need replace the default
            // exit handler in the runtime class loader
            // TODO: look at implementing a common core classloader, that removes the need for this sort of crappy hack
            curatedApplication.getBaseRuntimeClassLoader().loadClass(ApplicationLifecycleManager.class.getName()).getMethod("setDefaultExitCodeHandler", Consumer.class).invoke(null, new Consumer<Integer>() {

                @Override
                public void accept(Integer integer) {
                    if (restarting || ApplicationLifecycleManager.isVmShuttingDown() || context.isAbortOnFailedStart() || context.isTest()) {
                        return;
                    }
                    if (consoleContext == null) {
                        consoleContext = ConsoleStateManager.INSTANCE.createContext("Completed Application");
                    }
                    // this sucks, but when we get here logging is gone
                    // so we just setup basic console logging
                    InitialConfigurator.DELAYED_HANDLER.addHandler(new ConsoleHandler(ConsoleHandler.Target.SYSTEM_OUT, new ColorPatternFormatter("%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{3.}] (%t) %s%e%n")));
                    consoleContext.reset(new ConsoleCommand(' ', "Restarts the application", "to restart", 0, null, () -> {
                        consoleContext.reset();
                        RuntimeUpdatesProcessor.INSTANCE.doScan(true, true);
                    }), new ConsoleCommand('e', "Edits the command line parameters and restarts", "to edit command line args (currently '" + MessageFormat.GREEN + String.join(" ", context.getArgs()) + MessageFormat.RESET + "')", 100, new ConsoleCommand.HelpState(() -> BLUE, () -> String.join(" ", context.getArgs())), new Consumer<String>() {

                        @Override
                        public void accept(String args) {
                            try {
                                context.setArgs(CommandLineUtils.translateCommandline(args));
                            } catch (CommandLineException e) {
                                log.error("Failed to parse command line", e);
                                return;
                            }
                            consoleContext.reset();
                            RuntimeUpdatesProcessor.INSTANCE.doScan(true, true);
                        }
                    }));
                }
            });
            startCodeGenWatcher(deploymentClassLoader, codeGens, context.getBuildSystemProperties());
            runner = start.runMainClass(context.getArgs());
            RuntimeUpdatesProcessor.INSTANCE.setConfiguredInstrumentationEnabled(runner.getConfigValue("quarkus.live-reload.instrumentation", Boolean.class).orElse(false));
            firstStartCompleted = true;
            for (DevModeListener listener : ServiceLoader.load(DevModeListener.class)) {
                listeners.add(listener);
            }
            listeners.sort(Comparator.comparingInt(DevModeListener::order));
            for (DevModeListener listener : ServiceLoader.load(DevModeListener.class)) {
                try {
                    listener.afterFirstStart(runner);
                } catch (Exception e) {
                    log.warn("Unable to invoke 'afterFirstStart' of " + listener.getClass(), e);
                }
            }
        } catch (Throwable t) {
            Throwable rootCause = t;
            while (rootCause.getCause() != null) {
                rootCause = rootCause.getCause();
            }
            if (!(rootCause instanceof BindException)) {
                deploymentProblem = t;
                if (!context.isAbortOnFailedStart()) {
                    // we need to set this here, while we still have the correct TCCL
                    // this is so the config is still valid, and we can read HTTP config from application.properties
                    log.info("Attempting to start live reload endpoint to recover from previous Quarkus startup failure");
                    if (RuntimeUpdatesProcessor.INSTANCE != null) {
                        Thread.currentThread().setContextClassLoader(curatedApplication.getBaseRuntimeClassLoader());
                        try {
                            if (!InitialConfigurator.DELAYED_HANDLER.isActivated()) {
                                Class<?> cl = Thread.currentThread().getContextClassLoader().loadClass(LoggingSetupRecorder.class.getName());
                                cl.getMethod("handleFailedStart").invoke(null);
                            }
                            RuntimeUpdatesProcessor.INSTANCE.startupFailed();
                            // this exception has already been logged, so don't log it again
                            if (!(t instanceof ApplicationStartException)) {
                                log.error("Failed to start quarkus", t);
                            }
                        } catch (Exception e) {
                            close();
                            log.error("Failed to start quarkus", t);
                            log.error("Failed to recover after failed start", e);
                            // this is the end of the road, we just exit
                            // generally we only hit this if something is already listening on the HTTP port
                            // or the system config is so broken we can't start HTTP
                            System.exit(1);
                        }
                    }
                } else {
                    log.error("Failed to start quarkus", t);
                }
            }
        }
    } finally {
        Thread.currentThread().setContextClassLoader(old);
    }
}
Also used : ApplicationLifecycleManager(io.quarkus.runtime.ApplicationLifecycleManager) StartupAction(io.quarkus.bootstrap.app.StartupAction) ColorPatternFormatter(org.jboss.logmanager.formatters.ColorPatternFormatter) BindException(java.net.BindException) ApplicationStartException(io.quarkus.dev.appstate.ApplicationStartException) ConsoleCommand(io.quarkus.deployment.console.ConsoleCommand) ConsoleHandler(org.jboss.logmanager.handlers.ConsoleHandler) CommandLineException(org.apache.maven.shared.utils.cli.CommandLineException) BindException(java.net.BindException) ApplicationStartException(io.quarkus.dev.appstate.ApplicationStartException) CommandLineException(org.apache.maven.shared.utils.cli.CommandLineException) IOException(java.io.IOException) BiConsumer(java.util.function.BiConsumer) Consumer(java.util.function.Consumer) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader)

Example 4 with StartupAction

use of io.quarkus.bootstrap.app.StartupAction in project quarkus by quarkusio.

the class IsolatedDevModeMain method restartApp.

public synchronized void restartApp(Set<String> changedResources, ClassChangeInformation classChangeInformation) {
    restarting = true;
    if (consoleContext != null) {
        consoleContext.reset();
    }
    stop();
    Timing.restart(curatedApplication.getAugmentClassLoader());
    deploymentProblem = null;
    ClassLoader old = Thread.currentThread().getContextClassLoader();
    try {
        // ok, we have resolved all the deps
        try {
            StartupAction start = augmentAction.reloadExistingApplication(firstStartCompleted, changedResources, classChangeInformation);
            runner = start.runMainClass(context.getArgs());
            firstStartCompleted = true;
        } catch (Throwable t) {
            deploymentProblem = t;
            Throwable rootCause = t;
            while (rootCause.getCause() != null) {
                rootCause = rootCause.getCause();
            }
            if (!(rootCause instanceof BindException)) {
                log.error("Failed to start quarkus", t);
                Thread.currentThread().setContextClassLoader(curatedApplication.getAugmentClassLoader());
                LoggingSetupRecorder.handleFailedStart();
            }
        }
    } finally {
        restarting = false;
        Thread.currentThread().setContextClassLoader(old);
    }
}
Also used : StartupAction(io.quarkus.bootstrap.app.StartupAction) QuarkusClassLoader(io.quarkus.bootstrap.classloading.QuarkusClassLoader) BindException(java.net.BindException)

Example 5 with StartupAction

use of io.quarkus.bootstrap.app.StartupAction in project quarkus by quarkusio.

the class QuarkusMainTestExtension method doJavaStart.

private int doJavaStart(ExtensionContext context, Class<? extends QuarkusTestProfile> profile, String[] arguments) throws Exception {
    TracingHandler.quarkusStarting();
    Closeable testResourceManager = null;
    try {
        StartupAction startupAction = prepareResult.augmentAction.createInitialRuntimeApplication();
        Thread.currentThread().setContextClassLoader(startupAction.getClassLoader());
        QuarkusConsole.installRedirects();
        flushAllLoggers();
        installLoggerRedirect();
        QuarkusTestProfile profileInstance = prepareResult.profileInstance;
        // must be done after the TCCL has been set
        testResourceManager = (Closeable) startupAction.getClassLoader().loadClass(TestResourceManager.class.getName()).getConstructor(Class.class, Class.class, List.class, boolean.class, Map.class, Optional.class).newInstance(context.getRequiredTestClass(), profile != null ? profile : null, getAdditionalTestResources(profileInstance, startupAction.getClassLoader()), profileInstance != null && profileInstance.disableGlobalTestResources(), startupAction.getDevServicesProperties(), Optional.empty());
        testResourceManager.getClass().getMethod("init", String.class).invoke(testResourceManager, profile != null ? profile.getName() : null);
        Map<String, String> properties = (Map<String, String>) testResourceManager.getClass().getMethod("start").invoke(testResourceManager);
        startupAction.overrideConfig(properties);
        hasPerTestResources = (boolean) testResourceManager.getClass().getMethod("hasPerTestResources").invoke(testResourceManager);
        testResourceManager.getClass().getMethod("inject", Object.class).invoke(testResourceManager, context.getRequiredTestInstance());
        var result = startupAction.runMainClassBlocking(arguments);
        flushAllLoggers();
        return result;
    } catch (Throwable e) {
        if (!InitialConfigurator.DELAYED_HANDLER.isActivated()) {
            activateLogging();
        }
        try {
            if (testResourceManager != null) {
                testResourceManager.close();
            }
        } catch (Exception ex) {
            e.addSuppressed(ex);
        }
        throw e;
    } finally {
        uninstallLoggerRedirect();
        QuarkusConsole.uninstallRedirects();
        if (originalCl != null) {
            Thread.currentThread().setContextClassLoader(originalCl);
        }
    }
}
Also used : StartupAction(io.quarkus.bootstrap.app.StartupAction) Closeable(java.io.Closeable) ParameterResolutionException(org.junit.jupiter.api.extension.ParameterResolutionException) TestResourceManager(io.quarkus.test.common.TestResourceManager)

Aggregations

StartupAction (io.quarkus.bootstrap.app.StartupAction)5 QuarkusClassLoader (io.quarkus.bootstrap.classloading.QuarkusClassLoader)3 IOException (java.io.IOException)3 Consumer (java.util.function.Consumer)3 AugmentAction (io.quarkus.bootstrap.app.AugmentAction)2 RunningQuarkusApplication (io.quarkus.bootstrap.app.RunningQuarkusApplication)2 BuildChainBuilder (io.quarkus.builder.BuildChainBuilder)2 BuildContext (io.quarkus.builder.BuildContext)2 BuildStep (io.quarkus.builder.BuildStep)2 ApplicationLifecycleManager (io.quarkus.runtime.ApplicationLifecycleManager)2 TestResourceManager (io.quarkus.test.common.TestResourceManager)2 BindException (java.net.BindException)2 Path (java.nio.file.Path)2 ArrayList (java.util.ArrayList)2 AdditionalDependency (io.quarkus.bootstrap.app.AdditionalDependency)1 CuratedApplication (io.quarkus.bootstrap.app.CuratedApplication)1 QuarkusBootstrap (io.quarkus.bootstrap.app.QuarkusBootstrap)1 ClassPathElement (io.quarkus.bootstrap.classloading.ClassPathElement)1 InitialConfigurator (io.quarkus.bootstrap.logging.InitialConfigurator)1 ApplicationClassPredicateBuildItem (io.quarkus.deployment.builditem.ApplicationClassPredicateBuildItem)1