Package org.apache.openejb.maven.plugins

Source Code of org.apache.openejb.maven.plugins.TomEEEmbeddedMojo

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/
package org.apache.openejb.maven.plugins;

import org.apache.catalina.LifecycleState;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.openejb.core.ParentClassLoaderFinder;
import org.apache.openejb.core.ProvidedClassLoaderFinder;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.maven.util.MavenLogStreamFactory;
import org.apache.openejb.util.JuliLogStreamFactory;
import org.apache.tomee.embedded.Configuration;
import org.apache.tomee.embedded.Container;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Scanner;
import java.util.Set;
import java.util.logging.LogManager;
import java.util.logging.SimpleFormatter;

/**
* Run an Embedded TomEE.
*/
@Mojo(name = "run", requiresDependencyResolution = ResolutionScope.RUNTIME_PLUS_SYSTEM)
public class TomEEEmbeddedMojo extends AbstractMojo {
    @Parameter(defaultValue = "${project.packaging}")
    protected String packaging;

    @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}")
    protected File warFile;

    @Parameter(property = "tomee-embedded-plugin.http", defaultValue = "8080")
    protected int httpPort;

    @Parameter(property = "tomee-embedded-plugin.httpsPort", defaultValue = "8443")
    protected int httpsPort;

    @Parameter(property = "tomee-embedded-plugin.ajp", defaultValue = "8009")
    protected int ajpPort = 8009;

    @Parameter(property = "tomee-embedded-plugin.stop", defaultValue = "8005")
    protected int stopPort;

    @Parameter(property = "tomee-embedded-plugin.host", defaultValue = "localhost")
    protected String host;

    @Parameter(property = "tomee-embedded-plugin.lib", defaultValue = "${project.build.directory}/apache-tomee-embedded")
    protected String dir;

    @Parameter(property = "tomee-embedded-plugin.keystoreFile")
    protected String keystoreFile;

    @Parameter(property = "tomee-embedded-plugin.keystorePass")
    protected String keystorePass;

    @Parameter(property = "tomee-embedded-plugin.keystoreType", defaultValue = "JKS")
    protected String keystoreType;

    @Parameter(property = "tomee-embedded-plugin.clientAuth")
    protected String clientAuth;

    @Parameter(property = "tomee-embedded-plugin.keyAlias")
    protected String keyAlias;

    @Parameter(property = "tomee-embedded-plugin.sslProtocol")
    protected String sslProtocol;

    @Parameter
    protected File serverXml;

    @Parameter(property = "tomee-embedded-plugin.ssl", defaultValue = "false")
    protected boolean ssl;

    @Parameter(property = "tomee-embedded-plugin.quickSession", defaultValue = "true")
    protected boolean quickSession;

    @Parameter(property = "tomee-embedded-plugin.skipHttp", defaultValue = "false")
    protected boolean skipHttp;

    @Parameter(property = "tomee-embedded-plugin.classpathAsWar", defaultValue = "false")
    protected boolean classpathAsWar;

    @Parameter(property = "tomee-embedded-plugin.useProjectClasspath", defaultValue = "true")
    protected boolean useProjectClasspath;

    @Parameter(property = "tomee-embedded-plugin.modules", defaultValue = "${project.build.outputDirectory}")
    protected List<File> modules;

    @Parameter(property = "tomee-embedded-plugin.docBase", defaultValue = "${project.basedir}/src/main/webapp")
    protected File docBase;

    @Parameter(property = "tomee-embedded-plugin.context")
    protected String context;

    @Parameter // don't call it properties to avoid to break getConfig()
    protected Map<String, String> containerProperties;

    @Parameter(defaultValue = "${project}", readonly = true, required = true)
    private MavenProject project;

    @Parameter(property = "tomee-embedded-plugin.mavenLog", defaultValue = "true")
    private boolean mavenLog;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        if (!classpathAsWar && "pom".equals(packaging)) {
            getLog().warn("this project is a pom, it is not deployable");
            return;
        }

        final Properties originalSystProp = new Properties();
        originalSystProp.putAll(System.getProperties());

        // we use MavenLogStreamFactory but if user set some JUL config in properties we want to respect them
        configureJULIfNeeded();

        final Thread thread = Thread.currentThread();
        final ClassLoader loader = thread.getContextClassLoader();

        final String logFactory = System.getProperty("openejb.log.factory");
        MavenLogStreamFactory.setLogger(getLog());
        if (mavenLog) {
            System.setProperty("openejb.log.factory", MavenLogStreamFactory.class.getName()); // this line also preload the class (<cinit>)
            System.setProperty("openejb.jul.forceReload", "true");
        }

        final Container container = new Container();
        final Configuration config  = getConfig();
        container.setup(config);

        final Thread hook = new Thread() {
            @Override
            public void run() {
                if (container.getTomcat() != null && container.getTomcat().getServer().getState() != LifecycleState.DESTROYED) {
                    try {
                        if (!classpathAsWar) {
                            container.undeploy(warFile.getAbsolutePath());
                        }
                        container.stop();
                    } catch (final Exception e) {
                        getLog().error("can't stop TomEE", e);
                    }
                }
            }
        };

        try {
            container.start();
            SystemInstance.get().setComponent(ParentClassLoaderFinder.class, new ProvidedClassLoaderFinder(loader));

            Runtime.getRuntime().addShutdownHook(hook);

            if (!classpathAsWar) {
                container.deploy('/' + (context == null ? warFile.getName() : context), warFile, true);
            } else {
                if (useProjectClasspath) {
                    thread.setContextClassLoader(createClassLoader(loader));
                }
                container.deployClasspathAsWebApp(context, docBase); // null is handled properly so no issue here
            }

            getLog().info("TomEE embedded started on " + config.getHost() + ":" + config.getHttpPort());
        } catch (Exception e) {
            getLog().error("can't start TomEE", e);
        }

        try {
            String line;
            final Scanner scanner = new Scanner(System.in);
            while ((line = scanner.nextLine()) != null) {
                switch (line.trim()) {
                    case "exit":
                    case "quit":
                        Runtime.getRuntime().removeShutdownHook(hook);
                        container.close();
                        return;
                }
            }
        } catch (final Exception e) {
            Thread.interrupted();
        } finally {
            if (logFactory == null) {
                System.clearProperty("openejb.log.factory");
            } else {
                System.setProperty("openejb.log.factory", logFactory);
            }
            thread.setContextClassLoader(loader);
            System.setProperties(originalSystProp);
        }
    }

    private void configureJULIfNeeded() {
        if (containerProperties != null && "true".equalsIgnoreCase(containerProperties.get("openejb.jul.forceReload"))) {
            System.getProperties().putAll(containerProperties);
            new JuliLogStreamFactory(); // easiest way to support forceReload, note this doesn't do that much ATM
            final String simpleFormat = containerProperties.get("java.util.logging.SimpleFormatter.format");
            if (simpleFormat != null) {
                try {
                    final Field field = SimpleFormatter.class.getDeclaredField("format");
                    field.setAccessible(true);
                    final int modifiers = field.getModifiers();
                    if (Modifier.isFinal(modifiers)) {
                        final Field modifiersField = Field.class.getDeclaredField("modifiers");
                        modifiersField.setAccessible(true);
                        modifiersField.setInt(field, modifiers & ~Modifier.FINAL);
                    }
                    field.set(null, simpleFormat);
                } catch (final Throwable ignored) {
                    // no-op: don't block for it
                }
            }
        }
    }

    private ClassLoader createClassLoader(final ClassLoader parent) {
        final List<URL> urls = new ArrayList<>();
        for (final Artifact artifact : (Set<Artifact>) project.getArtifacts()) {
            try {
                urls.add(artifact.getFile().toURI().toURL());
            } catch (final MalformedURLException e) {
                getLog().warn("can't use artifact " + artifact.toString());
            }
        }
        for (final File file : modules) {
            if (file.exists()) {
                try {
                    urls.add(file.toURI().toURL());
                } catch (final MalformedURLException e) {
                    getLog().warn("can't use path " + file.getAbsolutePath());
                }
            } else {
                getLog().warn("can't find " + file.getAbsolutePath());
            }
        }
        return new URLClassLoader(urls.toArray(new URL[urls.size()]), parent);
    }

    private Configuration getConfig() { // lazy way but it works fine
        final Configuration config = new Configuration();
        for (final Field field : getClass().getDeclaredFields()) {
            try {
                final Field configField = Configuration.class.getDeclaredField(field.getName());
                field.setAccessible(true);
                configField.setAccessible(true);

                final Object value = field.get(this);
                if (value != null) {
                    configField.set(config, value);
                    getLog().debug("using " + field.getName() + " = " + value);
                }
            } catch (final NoSuchFieldException nsfe) {
                // ignored
            } catch (final Exception e) {
                 getLog().warn("can't initialize attribute " + field.getName());
            }

        }
        if (containerProperties != null) {
            final Properties props = new Properties();
            props.putAll(containerProperties);
            config.setProperties(props);
        }
        return config;
    }
}
TOP

Related Classes of org.apache.openejb.maven.plugins.TomEEEmbeddedMojo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.