![JAR search and dependency download from the Maven repository](/logo.png)
org.apache.openejb.maven.plugin.AbstractTomEEMojo Maven / Gradle / Ivy
/*
* 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.plugin;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.DefaultArtifactRepository;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.OpenEJBRuntimeException;
import org.apache.openejb.config.RemoteServer;
import org.apache.openejb.config.sys.Deployments;
import org.apache.openejb.config.sys.JaxbOpenejb;
import org.apache.openejb.config.sys.Openejb;
import org.apache.openejb.loader.Files;
import org.apache.openejb.loader.IO;
import org.apache.openejb.loader.Zips;
import org.apache.openejb.maven.plugin.cli.Args;
import org.apache.openejb.maven.util.XmlFormatter;
import org.apache.openejb.util.Join;
import org.apache.openejb.util.NetworkUtil;
import org.apache.openejb.util.OpenEjbVersion;
import org.apache.tomee.util.QuickServerXmlParser;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.util.FileUtils;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
import java.util.logging.SimpleFormatter;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE;
import static org.apache.maven.artifact.repository.ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN;
import static org.apache.maven.artifact.repository.ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY;
import static org.apache.maven.artifact.repository.ArtifactRepositoryPolicy.UPDATE_POLICY_NEVER;
import static org.apache.maven.artifact.versioning.VersionRange.createFromVersion;
import static org.apache.openejb.loader.Files.mkdirs;
import static org.apache.openejb.util.JarExtractor.delete;
import static org.codehaus.plexus.util.FileUtils.deleteDirectory;
import static org.codehaus.plexus.util.IOUtil.close;
import static org.codehaus.plexus.util.IOUtil.copy;
/**
* The type AbstractTomEEMojo is the base class to all the maven actions privided by the plugin.
*/
public abstract class AbstractTomEEMojo extends AbstractAddressMojo {
// if we get let say > 5 patterns like it we should create a LocationAnalyzer
// for < 5 patterns it should be fine
private static final String NAME_STR = "?name=";
private static final String UNZIP_PREFIX = "unzip:";
private static final String REMOVE_PREFIX = "remove:";
/**
* The constant QUIT_CMD.
*/
public static final String QUIT_CMD = "quit";
/**
* The constant EXIT_CMD.
*/
public static final String EXIT_CMD = "exit";
/**
* The constant TOM_EE.
*/
public static final String TOM_EE = "TomEE";
/**
* The Factory.
*/
@Component
protected ArtifactFactory factory;
/**
* The Resolver.
*/
@Component
protected ArtifactResolver resolver;
/**
* The Local.
*/
@Parameter(defaultValue = "${localRepository}", readonly = true)
protected ArtifactRepository local;
/**
* The Remote repos.
*/
@Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true)
protected List remoteRepos;
/**
* The Skip current project.
*/
@Parameter(property = "tomee-plugin.skipCurrentProject", defaultValue = "false")
protected boolean skipCurrentProject;
/**
* The TomEE version.
*/
@Parameter(property = "tomee-plugin.version", defaultValue = "-1")
protected String tomeeVersion;
/**
* The TomEE group id.
*/
@Parameter(property = "tomee-plugin.groupId", defaultValue = "org.apache.tomee")
protected String tomeeGroupId;
/**
* The TomEE artifact id.
*/
@Parameter(property = "tomee-plugin.artifactId", defaultValue = "apache-tomee")
protected String tomeeArtifactId;
/**
* while tar.gz is not managed it is readonly
*/
@Parameter(property = "tomee-plugin.type", defaultValue = "zip", readonly = true)
protected String tomeeType;
/**
* The Apache repos.
*/
@Parameter(property = "tomee-plugin.apache-repos", defaultValue = "snapshots")
protected String apacheRepos;
/**
* tomee classifier to use (webprofile or plus)
*/
@Parameter(property = "tomee-plugin.classifier", defaultValue = "webprofile")
protected String tomeeClassifier;
/**
* The TomEE shutdown port.
*/
@Parameter(property = "tomee-plugin.shutdown")
protected String tomeeShutdownPort;
/**
* The TomEE shutdown attempts.
*/
@Parameter(property = "tomee-plugin.shutdown.attempts", defaultValue = "60")
protected int tomeeShutdownAttempts;
/**
* The TomEE shutdown command.
*/
@Parameter(property = "tomee-plugin.shutdown-command", defaultValue = "SHUTDOWN")
protected String tomeeShutdownCommand;
/**
* The TomEE ajp port.
*/
@Parameter(property = "tomee-plugin.ajp")
protected String tomeeAjpPort;
/**
* The Args.
*/
@Parameter(property = "tomee-plugin.args")
protected String args;
/**
* The Debug.
*/
@Parameter(property = "tomee-plugin.debug", defaultValue = "false")
protected boolean debug;
/**
* The Simple log.
*/
@Parameter(property = "tomee-plugin.simple-log", defaultValue = "false")
protected boolean simpleLog;
/**
* The Extract wars.
*/
@Parameter(property = "tomee-plugin.extractWars", defaultValue = "false")
protected boolean extractWars;
/**
* The Strip war version.
*/
@Parameter(property = "tomee-plugin.stripWarVersion", defaultValue = "true")
protected boolean stripWarVersion;
/**
* The Strip version.
*/
@Parameter(property = "tomee-plugin.stripVersion", defaultValue = "false")
protected boolean stripVersion;
/**
* The Debug port.
*/
@Parameter(property = "tomee-plugin.debugPort", defaultValue = "5005")
protected int debugPort;
/**
* The Webapp resources.
*/
@Parameter(defaultValue = "${project.basedir}/src/main/webapp", property = "tomee-plugin.webappResources")
protected File webappResources;
/**
* The Webapp classes.
*/
@Parameter(defaultValue = "${project.build.outputDirectory}", property = "tomee-plugin.webappClasses")
protected File webappClasses;
/**
* The Catalina base.
*/
@Parameter(defaultValue = "${project.build.directory}/apache-tomee", property = "tomee-plugin.catalina-base")
protected File catalinaBase;
/**
* rename the current artifact
*/
@Parameter
protected String context;
/**
* relative to tomee.base.
*/
@Parameter
protected String webappDir;
/**
* relative to tomee.base.
*/
@Parameter(defaultValue = "apps")
protected String appDir;
/**
* relative to tomee.base.
*/
@Parameter(defaultValue = "lib")
protected String libDir;
/**
* The Main dir.
*/
@Parameter(defaultValue = "${project.basedir}/src/main")
protected File mainDir;
/**
* The Target.
*/
@Parameter(defaultValue = "${project.build.directory}")
protected File target;
/**
* The Config.
*/
@Parameter(property = "tomee-plugin.conf", defaultValue = "${project.basedir}/src/main/tomee/conf")
protected File config;
/**
* The Bin.
*/
@Parameter(property = "tomee-plugin.bin", defaultValue = "${project.basedir}/src/main/tomee/bin")
protected File bin;
/**
* The Lib.
*/
@Parameter(property = "tomee-plugin.lib", defaultValue = "${project.basedir}/src/main/tomee/lib")
protected File lib;
/**
* The System variables.
*/
@Parameter
protected Map systemVariables;
/**
* The Classpaths.
*/
@Parameter
protected List classpaths;
/**
* The Classpath separator.
*/
@Parameter(property = "tomee-plugin.classpathSeparator")
protected String classpathSeparator;
/**
* The Customizers.
*/
@Parameter
protected List customizers;
/**
* The Js customizers.
*/
@Parameter
protected List jsCustomizers;
/**
* The Groovy customizers.
*/
@Parameter
protected List groovyCustomizers;
/**
* The Project.
*/
@Parameter(defaultValue = "${project}", readonly = true, required = true)
protected MavenProject project;
/**
* forcing nice default for war development (WEB-INF/classes and web resources)
*/
@Parameter(property = "tomee-plugin.webappDefaultConfig", defaultValue = "false")
protected boolean webappDefaultConfig;
/**
* use a real random instead of secure random. saves few ms at startup.
*/
@Parameter(property = "tomee-plugin.quick-session", defaultValue = "true")
protected boolean quickSession;
/**
* force webapp to be reloadable
*/
@Parameter(property = "tomee-plugin.force-reloadable", defaultValue = "false")
protected boolean forceReloadable;
/**
* force webapp to be reloadable
*/
@Parameter(property = "tomee-plugin.jsp-development", defaultValue = "true")
protected boolean forceJspDevelopment;
/**
* supported formats:
* --> groupId:artifactId:version...
* --> unzip:groupId:artifactId:version...
* --> remove:prefix (often prefix = artifactId)
*/
@Parameter
protected List libs;
/**
* The Endorsed libs.
*/
@Parameter
protected List endorsedLibs;
/**
* The Javaagents.
*/
@Parameter
protected List javaagents;
/**
* The Persist javaagents.
*/
@Parameter(property = "tomee-plugin.persist-javaagents", defaultValue = "false")
protected boolean persistJavaagents;
/**
* The Webapps.
*/
@Parameter
protected List webapps;
/**
* The Apps.
*/
@Parameter
protected List apps;
/**
* The Classes.
*/
@Parameter(property = "tomee-plugin.classes", defaultValue = "${project.build.outputDirectory}", readonly = true)
protected File classes;
/**
* The War file.
*/
@Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.${project.packaging}")
protected File warFile;
/**
* The Work war file.
*/
@Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}", readonly = true)
protected File workWarFile;
/**
* The Final name.
*/
@Parameter(defaultValue = "${project.build.finalName}", readonly = true)
protected String finalName;
/**
* The Artifact id.
*/
@Parameter(defaultValue = "${project.artifactId}", readonly = true)
protected String artifactId;
/**
* The Remove default webapps.
*/
@Parameter(property = "tomee-plugin.remove-default-webapps", defaultValue = "true")
protected boolean removeDefaultWebapps;
/**
* The Deploy open ejb application.
*/
@Parameter(property = "tomee-plugin.deploy-openejb-internal-application", defaultValue = "false")
protected boolean deployOpenEjbApplication;
/**
* The Remove tomee webapp.
*/
@Parameter(property = "tomee-plugin.remove-tomee-webapps", defaultValue = "true")
protected boolean removeTomeeWebapp;
/**
* The Ejb remote.
*/
@Parameter(property = "tomee-plugin.ejb-remote", defaultValue = "true")
protected boolean ejbRemote;
/**
* The Packaging.
*/
@Parameter(defaultValue = "${project.packaging}", readonly = true)
protected String packaging;
/**
* The Check started.
*/
@Parameter(property = "tomee-plugin.check-started", defaultValue = "false")
protected boolean checkStarted;
/**
* The amount of attempts to check if the container is started.
*/
@Parameter(property = "tomee-plugin.check-started-attempts", defaultValue = "60")
protected int checkStartedAttempts;
/**
* The Use console.
*/
@Parameter(property = "tomee-plugin.use-console", defaultValue = "true")
protected boolean useConsole;
/**
* The TomEE already installed.
*/
@Parameter(property = "tomee-plugin.exiting", defaultValue = "false")
protected boolean tomeeAlreadyInstalled;
/**
* The current user system settings for use in Maven.
*/
@Parameter(defaultValue = "${settings}", readonly = true)
protected Settings settings;
/**
* use openejb-standalone automatically instead of TomEE
*/
@Parameter(property = "tomee-plugin.openejb", defaultValue = "false")
protected boolean useOpenEJB;
/**
* for TomEE and wars only, which docBase to use for this war.
*/
@Parameter
protected List docBases;
/**
* for TomEE and wars only, add some external repositories to classloader.
*/
@Parameter
protected List externalRepositories;
/**
* server.xml configured inlined (is Server tag is the first child of inlinedServerXml)
*/
@Parameter
protected PlexusConfiguration inlinedServerXml;
/**
* tomee.xml configured inlined (is tomee tag is the first child of inlinedTomEEXml)
*/
@Parameter
protected PlexusConfiguration inlinedTomEEXml;
/**
* if a file is already there when unpacking tomee zip should it be overriden?
*/
@Parameter(property = "tomee-plugin.override-on-unzip", defaultValue = "true")
protected boolean overrideOnUnzip;
/**
* if a file is already there when unpacking tomee zip should it be overriden?
*/
@Parameter(property = "tomee-plugin.skip-root-folder-on-unzip", defaultValue = "true")
protected boolean skipRootFolderOnUnzip;
/**
* the actual path used in server.xml for the https keystore if relevant.
* Common usage will be to put in src/main/tomee/conf a keystore foo.jks
* and set this value to ${catalina.base}/foo.jks.
*
* Note: if not set we'll check for any *.jks in conf/. You can set it to "ignore" to skip this.
*/
@Parameter(property = "tomee-plugin.keystore")
protected String keystore;
/**
* The Deployed file.
*/
protected File deployedFile = null;
/**
* The Server.
*/
protected RemoteServer server = null;
/**
* The Container.
*/
protected String container = TOM_EE;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
fixConfig();
if ("-1".equals(tomeeVersion)) {
tomeeVersion = OpenEjbVersion.get().getVersion();
}
if (!tomeeAlreadyInstalled) {
final Collection existingWebapps; // added before using the plugin with maven dependency plugin or sthg like that
if (removeDefaultWebapps) {
existingWebapps = webappsAlreadyAdded();
} else {
existingWebapps = Collections.emptyList();
}
unzip(resolve());
if (inlinedServerXml != null && inlinedServerXml.getChildCount() > 0) {
final File serverXml = new File(catalinaBase, "conf/server.xml");
try {
FileUtils.forceMkdir(serverXml.getParentFile());
FileUtils.fileWrite(serverXml, XmlFormatter.format(inlinedServerXml.getChild(0).toString()));
} catch (final Exception e) {
throw new MojoExecutionException(e.getMessage(), e);
}
}
if (inlinedTomEEXml != null && inlinedTomEEXml.getChildCount() > 0) {
final File tomeeXml = new File(catalinaBase, "conf/tomee.xml");
try {
FileUtils.forceMkdir(tomeeXml.getParentFile());
FileUtils.fileWrite(tomeeXml, XmlFormatter.format(inlinedTomEEXml.getChild(0).toString()));
} catch (final Exception e) {
throw new MojoExecutionException(e.getMessage(), e);
}
}
overrideConf(config, "conf");
overrideServerXml();
alignConfigOnServerXmlCurrentConfig();
if (removeDefaultWebapps) { // do it first to let add other war
removeDefaultWebapps(removeTomeeWebapp, existingWebapps);
}
if (classpaths == null) { // NPE protection for activateSimpleLog() and run()
classpaths = new ArrayList<>();
}
if (simpleLog) {
activateSimpleLog();
}
copyLibs(libs, new File(catalinaBase, libDir), "jar");
copyLibs(endorsedLibs, new File(catalinaBase, "endorsed"), "jar");
copyLibs(webapps, new File(catalinaBase, webappDir), "war");
copyLibs(apps, new File(catalinaBase, appDir), "jar");
overrideConf(lib, "lib");
final Collection copied = overrideConf(bin, "bin");
for (final File copy : copied) {
if (copy.getName().endsWith(".sh")) {
if (!copy.setExecutable(true)) {
getLog().warn("can't make " + copy.getPath() + " executable");
}
}
}
if (!skipCurrentProject) {
copyWar();
}
if (customizers != null) {
final Thread thread = Thread.currentThread();
final ClassLoader currentLoader = thread.getContextClassLoader();
final ClassLoader tccl = createClassLoader(currentLoader);
thread.setContextClassLoader(tccl);
try {
// a customizer is a Runnable with or without a constructor taking a File as parameter (catalina base)
// one goal is to avoid coupling as much as possible with this plugin
//
// if really needed we could introduce a Customizer interface but then it has more impacts on your packaging/config
for (final String customizer : customizers) {
try {
final Class> clazz = tccl.loadClass(customizer);
try {
clazz.getMethod("main", String[].class)
.invoke(null, new String[]{catalinaBase.getAbsolutePath()});
} catch (final NoSuchMethodException noMainEx) {
try {
final Constructor> cons = clazz.getConstructor(File.class);
Runnable.class.cast(cons.newInstance(catalinaBase)).run();
} catch (final NoSuchMethodException e) {
try {
Runnable.class.cast(clazz.newInstance()).run();
} catch (final Exception e1) {
throw new MojoExecutionException("can't create customizer: " + currentLoader, e);
}
} catch (final InvocationTargetException | InstantiationException | IllegalAccessException e) {
throw new MojoExecutionException("can't create customizer: " + currentLoader, e);
}
} catch (final InvocationTargetException | IllegalAccessException e) {
throw new MojoExecutionException("can't find customizer: " + currentLoader, e);
}
} catch (final ClassNotFoundException e) {
throw new MojoExecutionException("can't find customizer: " + currentLoader, e);
}
}
} finally {
try {
if (tccl != null && Closeable.class.isInstance(tccl)) {
Closeable.class.cast(tccl).close();
}
} catch (final IOException e) {
// no-op
}
thread.setContextClassLoader(currentLoader);
}
}
scriptCustomization(jsCustomizers, "js");
scriptCustomization(groovyCustomizers, "groovy");
} else {
alignConfigOnServerXmlCurrentConfig();
}
run();
}
private void scriptCustomization(final List customizers, final String ext) throws MojoExecutionException {
if (customizers != null) {
final ScriptEngine engine = new ScriptEngineManager().getEngineByExtension(ext);
if (engine == null) {
throw new IllegalStateException("No engine for " + ext + ". Maybe add the JSR223 implementation as plugin dependency.");
}
for (final String js : customizers) {
try {
final SimpleBindings bindings = new SimpleBindings();
bindings.put("catalinaBase", catalinaBase.getAbsolutePath());
bindings.put("resolver", new Resolver() {
@Override
public File resolve(final String group, final String artifact, final String version,
final String classifier, final String type) {
try {
return AbstractTomEEMojo.this.resolve(group, artifact, version, classifier, type).resolved;
} catch (final ArtifactResolutionException | ArtifactNotFoundException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public File resolve(final String group, final String artifact, final String version) {
try {
return AbstractTomEEMojo.this.resolve(group, artifact, version, null, "jar").resolved;
} catch (final ArtifactResolutionException | ArtifactNotFoundException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public File resolve(final String group, final String artifact, final String version, final String type) {
try {
return AbstractTomEEMojo.this.resolve(group, artifact, version, null, type).resolved;
} catch (final ArtifactResolutionException | ArtifactNotFoundException e) {
throw new IllegalArgumentException(e);
}
}
});
engine.eval(new StringReader(js), bindings);
} catch (final ScriptException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
}
}
}
private void alignConfigOnServerXmlCurrentConfig() {
final File sXml = new File(catalinaBase, "conf/server.xml");
if (sXml.isFile()) {
final QuickServerXmlParser quickServerXmlParser = QuickServerXmlParser.parse(sXml, false);
tomeeHttpPort = quickServerXmlParser.value("HTTP", null);
tomeeHttpsPort = quickServerXmlParser.value("HTTPS", null);
tomeeAjpPort = quickServerXmlParser.value("AJP", null);
tomeeShutdownPort = quickServerXmlParser.value("STOP", null);
final String host = quickServerXmlParser.value("host", null);
if (host != null) {
tomeeHost = host;
}
final String appBase = quickServerXmlParser.value("app-base", null);
if (appBase != null) {
webappDir = appBase;
}
}
if (webappDir == null) {
webappDir = "webapps";
}
}
@SuppressWarnings("unchecked")
private ClassLoader createClassLoader(final ClassLoader parent) {
final List urls = new ArrayList<>();
for (final Artifact artifact : (Collection) project.getArtifacts()) {
try {
urls.add(artifact.getFile().toURI().toURL());
} catch (final MalformedURLException e) {
getLog().warn("can't use artifact " + artifact.toString());
}
}
if (classes != null && classes.exists()) {
try {
urls.add(classes.toURI().toURL());
} catch (final MalformedURLException e) {
getLog().warn("can't use path " + classes.getAbsolutePath());
}
}
return new URLClassLoader(urls.toArray(new URL[urls.size()]), parent);
}
/**
* Fix config.
*/
protected void fixConfig() {
if (useOpenEJB) {
tomeeGroupId = "org.apache.tomee";
tomeeArtifactId = "openejb-standalone";
tomeeClassifier = null;
tomeeShutdownCommand = "Q";
if ("8005".equals(tomeeShutdownPort)) { // default admin port
tomeeShutdownPort = "4200";
}
if (tomeeVersion.startsWith("2.")) {
tomeeVersion = OpenEjbVersion.get().getVersion();
}
if (catalinaBase.getName().equals("apache-tomee") && catalinaBase.getParentFile().equals(target)) {
catalinaBase = new File(target, "apache-openejb");
}
if (config.getParentFile().getName().equals("tomee") && config.getParentFile().getParentFile().equals(mainDir)) {
config = new File(mainDir, "openejb/conf");
}
if (lib.getParentFile().getName().equals("tomee") && lib.getParentFile().getParentFile().equals(mainDir)) {
lib = new File(mainDir, "openejb/lib");
}
if (bin.getParentFile().getName().equals("tomee") && bin.getParentFile().getParentFile().equals(mainDir)) {
bin = new File(mainDir, "openejb/bin");
}
}
}
/**
* Gets additional classpath.
*
* @return the additional classpath
*/
protected String getAdditionalClasspath() {
if (!classpaths.isEmpty()) {
final StringBuilder cpBuilder = new StringBuilder();
for (final String cp : classpaths) {
final String[] split = cp.split(":");
if (split.length >= 3 /*GAV*/) {
final FileWithMavenMeta jar;
try {
jar = resolve(split[0], split[1], split[2],
split.length > 4 ? split[4] : null, split.length > 3 ? split[3] : "jar");
} catch (final ArtifactResolutionException | ArtifactNotFoundException e) {
throw new IllegalArgumentException(e);
}
final File classpathRoot = new File(catalinaBase, "boot");
if (!classpathRoot.isDirectory()) {
mkdirs(classpathRoot);
}
final File target = new File(classpathRoot, stripVersion ? jar.stripVersion(true) : jar.resolved.getName());
try {
IO.copy(jar.resolved, target);
} catch (final IOException e) {
throw new IllegalArgumentException(e);
}
cpBuilder.append("${openejb.base}/boot/").append(target.getName());
} else { // else plain path
cpBuilder.append(cp);
}
if (classpathSeparator == null) {
classpathSeparator = File.pathSeparator;
}
cpBuilder.append(classpathSeparator);
}
return cpBuilder.substring(0, cpBuilder.length() - 1); // Dump the final path separator
}
return null;
}
private List webappsAlreadyAdded() {
final List list = new ArrayList();
final File webapps = new File(catalinaBase, webappDirOrImplicitDefault());
if (webapps.exists() && webapps.isDirectory()) {
final File[] files = webapps.listFiles();
if (files != null) {
for (final File f : files) {
list.add(f.getName());
}
}
}
return list;
}
private String webappDirOrImplicitDefault() {
return webappDir == null ? "webapps" : webappDir;
}
private void activateSimpleLog() {
// replacing java.util.logging.SimpleFormatter by SimpleTomEEFormatter
final File loggingProperties = new File(catalinaBase, "conf/logging.properties");
if (loggingProperties.exists() && !new File(config, "conf/logging.properties").exists()) {
try {
String content = IO.slurp(loggingProperties);
if (!content.contains("java.util.logging.ConsoleHandler.formatter")) {
content += System.getProperty("line.separator") + "java.util.logging.ConsoleHandler.formatter = org.apache.tomee.jul.formatter.SimpleTomEEFormatter";
} else {
content = content.replace(SimpleFormatter.class.getName(), "org.apache.tomee.jul.formatter.SimpleTomEEFormatter");
}
doWrite(loggingProperties, content);
} catch (final Exception e) {
getLog().error("Can't set SimpleTomEEFormatter", e);
}
}
}
private void removeDefaultWebapps(final boolean removeTomee, final Collection providedWebapps) {
final File webapps = new File(catalinaBase, webappDirOrImplicitDefault());
if (webapps.isDirectory()) {
final File[] files = webapps.listFiles();
if (null != files) {
for (final File webapp : files) {
final String name = webapp.getName();
if (webapp.isDirectory() && !providedWebapps.contains(name) && (removeTomee || !name.equals("tomee"))) {
try {
deleteDirectory(webapp);
} catch (final IOException ignored) {
// no-op
}
}
}
}
}
getLog().info("Removed not mandatory default webapps");
}
private void copyLibs(final List files, final File destParent, final String defaultType) {
if (files == null || files.isEmpty()) {
return;
}
if (!destParent.exists() && !destParent.mkdirs()) {
getLog().warn("can't create '" + destParent.getPath() + "'");
}
for (final String file : files) {
updateLib(file, destParent, defaultType);
}
}
private void updateLib(final String rawLib, final File rawDestParent, final String defaultType) {
InputStream is = null;
OutputStream os = null;
// special hook to get more info
String lib = rawLib;
String extractedName = null;
if (lib.contains(NAME_STR)) {
lib = lib.substring(0, rawLib.indexOf(NAME_STR));
extractedName = rawLib.substring(rawLib.indexOf(NAME_STR) + NAME_STR.length(), rawLib.length());
if (!extractedName.endsWith(".jar") && !extractedName.endsWith(".war")
&& !extractedName.endsWith(".ear") && !extractedName.endsWith(".rar")) {
extractedName = extractedName + "." + defaultType;
}
}
final boolean isWar = "war".equals(defaultType);
final boolean isExplodedWar = extractWars && isWar;
boolean unzip = isExplodedWar;
if (lib.startsWith(UNZIP_PREFIX)) {
lib = lib.substring(UNZIP_PREFIX.length());
unzip = true;
}
File destParent = rawDestParent;
if (lib.startsWith(REMOVE_PREFIX)) {
final String prefix = lib.substring(REMOVE_PREFIX.length());
final File[] files = destParent.listFiles(new FilenameFilter() {
@Override
public boolean accept(final File dir, final String name) {
return name.startsWith(prefix);
}
});
if (files != null) {
for (final File file : files) {
if (!IO.delete(file)) {
file.deleteOnExit();
}
getLog().info("Deleted " + file.getPath());
}
}
} else {
try {
final FileWithMavenMeta file = mvnToFile(lib, defaultType);
if (extractedName == null && (stripVersion || isWar && stripWarVersion)) {
extractedName = isCurrentArtifact(file) && file.version != null ? finalName.replace("-" + file.version, "") :
file.stripVersion(!isExplodedWar);
}
if (!unzip) {
final File dest;
if (extractedName == null) {
dest = new File(destParent, file.resolved.getName());
} else {
dest = new File(destParent, extractedName);
}
is = new BufferedInputStream(new FileInputStream(file.resolved));
os = new BufferedOutputStream(new FileOutputStream(dest));
copy(is, os);
getLog().info("Copied '" + lib + "' in '" + dest.getAbsolutePath());
} else {
if (isExplodedWar) {
destParent = Files.mkdirs(new File(rawDestParent, extractedName != null ?
extractedName : file.resolved.getName().replace(".war", "")));
}
Zips.unzip(file.resolved, destParent, !isExplodedWar);
getLog().info("Unzipped '" + lib + "' in '" + destParent.getAbsolutePath());
}
} catch (final Exception e) {
getLog().error(e.getMessage(), e);
throw new TomEEException(e.getMessage(), e);
} finally {
close(is);
close(os);
}
}
}
private boolean isCurrentArtifact(final FileWithMavenMeta file) {
return file.artifact.equals(artifactId);
}
private FileWithMavenMeta mvnToFile(final String lib, final String defaultType) throws ArtifactResolutionException, ArtifactNotFoundException {
final String[] infos = lib.split(":");
final String classifier;
final String type;
if (infos.length < 3) {
throw new TomEEException("format for librairies should be ::[:[:]]");
}
if (infos.length >= 4) {
type = infos[3];
} else {
type = defaultType;
}
if (infos.length == 5) {
classifier = infos[4];
} else {
classifier = null;
}
return resolve(infos[0], infos[1], infos[2], classifier, type);
}
private FileWithMavenMeta resolve(final String group, final String artifact, final String version, final String classifier, final String type) throws ArtifactResolutionException, ArtifactNotFoundException {
final Artifact dependencyArtifact = factory.createDependencyArtifact(group, artifact, createFromVersion(version), type, classifier, SCOPE_COMPILE);
resolver.resolve(dependencyArtifact, remoteRepos, local);
return new FileWithMavenMeta(group, artifact, version, classifier, type, dependencyArtifact.getFile());
}
private void copyWar() {
if ("pom".equals(packaging)) {
return;
}
final boolean war = "war".equals(packaging);
final String name = destinationName();
File out;
if (war) {
out = new File(catalinaBase, webappDir + "/" + name);
} else {
final File parent = new File(catalinaBase, appDir);
if (!parent.exists() && !parent.mkdirs()) {
getLog().warn("can't create '" + parent.getPath() + "'");
}
out = new File(parent, name);
}
delete(out);
if (!warFile.isDirectory() && name.endsWith("." + packaging)) {
final String dir = name.substring(0, name.lastIndexOf('.'));
final File unpacked;
if (war) {
unpacked = new File(catalinaBase, webappDir + "/" + dir);
} else {
unpacked = new File(catalinaBase, appDir + "/" + dir);
}
delete(unpacked);
}
if (extractWars) {
warFile = workWarFile;
if (context == null && out.getName().endsWith(".war") && !warFile.getName().endsWith(".war")) {
out = new File(out.getParentFile(), warFile.getName());
}
}
if (warFile.exists() && warFile.isDirectory()) {
try {
IO.copyDirectory(warFile, out);
} catch (final IOException e) {
throw new TomEEException(e.getMessage(), e);
}
} else if (warFile.exists()) {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(warFile);
os = new FileOutputStream(out);
copy(is, os);
getLog().info("Installed '" + warFile.getAbsolutePath() + "' in " + out.getAbsolutePath());
} catch (final Exception e) {
throw new TomEEException(e.getMessage(), e);
} finally {
close(is);
close(os);
}
} else {
getLog().warn("'" + warFile + "' doesn't exist, ignoring (maybe run mvn package before this plugin)");
}
deployedFile = out;
}
/**
* Destination name string.
*
* @return the string
*/
protected String destinationName() {
if (context != null) {
if (!context.contains(".") && !warFile.isDirectory()) {
return context + "." + packaging;
}
return context;
}
return warFile.getName();
}
private void overrideServerXml() {
final File serverXml = new File(catalinaBase, "conf/server.xml");
if (!serverXml.exists()) { // openejb
return;
}
final QuickServerXmlParser parser = QuickServerXmlParser.parse(serverXml);
final String original = read(serverXml);
String value = original;
if (tomeeHttpsPort != null && tomeeHttpsPort.length() > 0 && parser.value("HTTPS", null) == null) {
String keystorePath = keystore != null ? keystore : parser.keystore();
if (keystorePath == null) {
final File conf = new File(catalinaBase, "conf");
if (conf.isDirectory()) {
final File[] jks = conf.listFiles(new FilenameFilter() {
@Override
public boolean accept(final File dir, final String name) {
return name.endsWith(".jks");
}
});
if (jks != null && jks.length == 1) {
keystorePath = "${catalina.base}/conf/" + jks[0].getName();
} else {
throw new IllegalArgumentException("Ambiguous jks in conf/,please use to force it.");
}
}
}
if (keystorePath == null) {
throw new IllegalArgumentException("No keystore specified, please use ");
}
// ensure connector is not commented
value = value.replace("", "\n"
+ " \n");
}
if (tomeeHttpPort != null) {
value = value.replace("\"" + parser.http() + "\"", "\"" + tomeeHttpPort + "\"");
}
if (tomeeHttpsPort != null) {
value = value.replace("\"" + parser.https() + "\"", "\"" + tomeeHttpsPort + "\"");
}
if (tomeeAjpPort != null) {
value = value.replace("\"" + parser.ajp() + "\"", "\"" + tomeeAjpPort + "\"");
}
if (tomeeShutdownPort != null) {
value = value.replace("\"" + parser.stop() + "\"", "\"" + tomeeShutdownPort + "\"");
}
if (webappDir != null) {
value = value.replace("\"" + parser.value("app-base", "webapps") + "\"", "\"" + webappDir + "\"");
}
if (tomeeHost != null) {
value = value.replace("\"" + parser.host() + "\"", "\"" + tomeeHost + "\"");
}
if (!original.equals(value)) {
FileWriter writer = null;
try {
writer = new FileWriter(serverXml);
writer.write(value);
} catch (final IOException e) {
throw new TomEEException(e.getMessage(), e);
} finally {
close(writer);
}
}
}
private static String read(final File file) {
FileInputStream in = null;
try {
in = new FileInputStream(file);
final StringBuilder sb = new StringBuilder();
int i = in.read();
while (i != -1) {
sb.append((char) i);
i = in.read();
}
return sb.toString();
} catch (final Exception e) {
throw new TomEEException(e.getMessage(), e);
} finally {
close(in);
}
}
private Collection overrideConf(final File dir, final String baseDir) {
if (!dir.exists()) {
return Collections.emptyList();
}
final File[] files = dir.listFiles();
if (files != null) {
final Collection copied = new ArrayList<>();
for (final File f : files) {
if (f.isHidden()) {
continue;
}
final String file = baseDir + "/" + f.getName();
final File destination = new File(catalinaBase, file);
if (f.isDirectory()) {
Files.mkdirs(destination);
try {
IO.copyDirectory(f, destination);
} catch (final IOException e) {
throw new TomEEException(e.getMessage(), e);
}
} else {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(f);
out = new FileOutputStream(destination);
copy(in, out);
copied.add(f);
getLog().info("Override '" + file + "'");
} catch (final Exception e) {
throw new TomEEException(e.getMessage(), e);
} finally {
close(in);
close(out);
}
}
}
return copied;
}
return Collections.emptyList();
}
/**
* Run.
*/
protected void run() {
if (classpaths == null) { // NPE protection when execute is skipped and mojo delegates to run directly
classpaths = new ArrayList<>();
}
// init ports if needed
tomeeHttpPort = getOrInitPort(tomeeHttpPort);
tomeeHttpsPort = getOrInitPort(tomeeHttpsPort);
tomeeAjpPort = getOrInitPort(tomeeAjpPort);
tomeeShutdownPort = getOrInitPort(tomeeShutdownPort);
final List strings = generateJVMArgs();
// init env for RemoteServer
System.setProperty("openejb.home", catalinaBase.getAbsolutePath());
if (debug) {
System.setProperty("openejb.server.debug", "true");
System.setProperty("server.debug.port", Integer.toString(debugPort));
}
System.setProperty("server.shutdown.port", String.valueOf(tomeeShutdownPort));
System.setProperty("server.shutdown.command", tomeeShutdownCommand);
// We might need to override static cached env vars in RemoteServer
// Reason: Multiple execution in same JVM, i.e. in Maven Integration Tests
Properties override = new Properties();
override.setProperty("openejb.home", System.getProperty("openejb.home"));
if (debug) {
override.setProperty("openejb.server.debug", System.getProperty("openejb.server.debug"));
override.setProperty("server.debug.port", System.getProperty("server.debug.port"));
}
override.setProperty("server.shutdown.port", System.getProperty("server.shutdown.port"));
override.setProperty("server.shutdown.command", System.getProperty("server.shutdown.command"));
server = new RemoteServer(override, getConnectAttempts(), debug);
server.setAdditionalClasspath(getAdditionalClasspath());
addShutdownHooks(server); // some shutdown hooks are always added (see UpdatableTomEEMojo)
if (TOM_EE.equals(container)) {
try {
server.setPortStartup(Integer.parseInt(tomeeHttpPort == null ? tomeeHttpsPort : tomeeHttpPort));
} catch (final NumberFormatException nfe) {
// no-op
}
getLog().info("Running '" + getClass().getName().replace("TomEEMojo", "").toLowerCase(Locale.ENGLISH)
+ "'. Configured TomEE in plugin is " + tomeeHost + ":" + server.getPortStartup()
+ " (plugin shutdown port is " + tomeeShutdownPort + " and https port is " + tomeeHttpsPort + ")");
} else {
getLog().info("Running '" + getClass().getSimpleName().replace("TomEEMojo", "").toLowerCase(Locale.ENGLISH));
}
final InputStream originalIn = System.in; // piped when starting remote server so saving it
serverCmd(server, strings);
if (getWaitTomEE()) {
final CountDownLatch stopCondition = new CountDownLatch(1);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
stopServer(stopCondition);
}
});
if (useConsole) {
final Scanner reader = new Scanner(originalIn);
System.out.flush();
getLog().info("Waiting for command: " + availableCommands());
String line;
while ((line = getNextLine(reader)) != null) {
if (isQuit(line)) {
break;
}
if ("ignore".equals(line)) {
continue;
}
if (!handleLine(line.trim())) {
System.out.flush();
getLog().warn("Command '" + line + "' not understood. Use one of " + availableCommands());
}
}
reader.close();
stopServer(stopCondition); // better than using shutdown hook since it doesn't rely on the hook which are not sent by eclipse for instance
}
try {
stopCondition.await();
} catch (final InterruptedException e) {
// no-op
}
}
}
private static String getOrInitPort(final String raw) {
try {
if (Integer.parseInt(raw) <= 0) {
return Integer.toString(NetworkUtil.getNextAvailablePort());
}
} catch (final NumberFormatException nfe) {
// no-op, surely a placeholder
}
return raw;
}
private String getNextLine(final Scanner reader) {
try {
return reader.nextLine();
} catch (final NoSuchElementException e) {
return "ignore";
}
}
/**
* Generate jvm args list.
*
* @return the list
*/
protected List generateJVMArgs() {
final String deployOpenEjbAppKey = "openejb.system.apps";
final String servletCompliance = "org.apache.catalina.STRICT_SERVLET_COMPLIANCE";
boolean deactivateStrictServletCompliance = args == null || !args.contains(servletCompliance);
if (webappDefaultConfig) {
forceDefaultForNiceWebAppDevelopment();
}
final List strings = new ArrayList<>();
if (systemVariables != null) {
for (final Map.Entry entry : systemVariables.entrySet()) {
final String key = entry.getKey();
if (servletCompliance.equals(key)) {
deactivateStrictServletCompliance = false;
}
final String value = entry.getValue();
if (value == null) {
strings.add("-D" + key);
} else {
strings.add(String.format("-D%s=%s", key, value));
}
if (deployOpenEjbAppKey.equals(key)) {
deployOpenEjbApplication = true;
}
}
}
if (deactivateStrictServletCompliance) {
strings.add("-D" + servletCompliance + "=false");
}
if (quickSession) {
strings.add("-Dopenejb.session.manager=org.apache.tomee.catalina.session.QuickSessionManager");
}
if (removeTomeeWebapp && ejbRemote) { // if we have tomee webapp no need to activate ejb remote support this way
strings.add("-Dtomee.remote.support=true");
}
if (!deployOpenEjbApplication) { // true is the default so don't need to set the property
if (args == null || !args.contains("-D" + deployOpenEjbAppKey)) {
strings.add("-D" + deployOpenEjbAppKey + "=false");
}
}
if (args != null) {
strings.addAll(Args.parse(args));
}
if (javaagents != null) {
addJavaagents(strings);
}
if (forceReloadable) {
strings.add("-Dtomee.force-reloadable=true");
}
if (!getWaitTomEE()) {
strings.add("-Dtomee.noshutdownhook=true");
}
String appName = null; // computed lazily
if (docBases != null && !docBases.isEmpty()) {
if ("war".equals(packaging)) {
appName = destinationName().replace(".war", "");
if (appName.startsWith("/")) {
appName = appName.substring(1);
}
strings.add("-Dtomee." + appName + ".docBases=" + filesToString(docBases));
} else {
getLog().warn("docBases parameter only valid for a war");
}
}
if (externalRepositories != null && !externalRepositories.isEmpty()) {
if ("war".equals(packaging)) {
appName = appName == null ? destinationName().replace(".war", "") : appName;
if (appName.startsWith("/")) {
appName = appName.substring(1);
}
strings.add("-Dtomee." + appName + ".externalRepositories=" + filesToString(externalRepositories));
} else {
getLog().warn("externalRepositories parameter only valid for a war");
}
}
if (forceJspDevelopment) {
getLog().info("TomEE will run in development mode");
strings.add("-Dtomee.jsp-development=true");
}
return strings;
}
private void addJavaagents(final List strings) {
final String existingJavaagent = "\\\"-javaagent:$CATALINA_HOME/lib/openejb-javaagent.jar\\\"";
final StringBuilder javaagentString = new StringBuilder(existingJavaagent);
for (final String rawJavaagent : javaagents) {
final String javaagent;
final String args;
int argsIdx = rawJavaagent.indexOf('=');
if (argsIdx < 0) {
argsIdx = rawJavaagent.indexOf('?');
}
if (argsIdx > 0) {
javaagent = rawJavaagent.substring(0, argsIdx);
args = rawJavaagent.substring(argsIdx);
} else {
javaagent = rawJavaagent;
args = "";
}
String path = javaagent;
if (!new File(javaagent).isFile()) {
try {
final FileWithMavenMeta jar = mvnToFile(javaagent, "jar");
if (persistJavaagents) {
final File javaagentFolder = new File(catalinaBase, "javaagent");
Files.mkdirs(javaagentFolder);
String name = jar.resolved.getName();
if (stripVersion) {
name = jar.stripVersion(true);
}
path = "$CATALINA_HOME/javaagent/" + name;
IO.copy(jar.resolved, new File(javaagentFolder, name));
}
strings.add("-javaagent:" + jar.resolved.getAbsolutePath() + args);
} catch (final Exception e) {
getLog().warn("Can't find " + javaagent);
strings.add("-javaagent:" + javaagent + args);
}
} else {
strings.add("-javaagent:" + javaagent + args);
}
if (persistJavaagents) {
javaagentString.append(" -javaagent:").append(path).append(args);
}
}
if (persistJavaagents) {
try {
{
final File catalinaSh = new File(catalinaBase, "bin/catalina.sh");
final String content = IO.slurp(catalinaSh).replace(existingJavaagent, javaagentString.toString());
doWrite(catalinaSh, content);
}
{
final File catalinaBat = new File(catalinaBase, "bin/catalina.bat");
final String content = IO.slurp(catalinaBat)
.replace(
"\"-javaagent:%CATALINA_HOME%\\lib\\openejb-javaagent.jar\"",
javaagentString.toString()
.replace('\'', '"')
.replace('/', '\\')
.replace("$CATALINA_HOME", "%CATALINA_HOME%"));
doWrite(catalinaBat, content);
}
} catch (final IOException ioe) {
throw new OpenEJBRuntimeException(ioe);
}
}
}
private void forceDefaultForNiceWebAppDevelopment() {
if (!deployOpenEjbApplication) {
getLog().info("Forcing deployOpenEjbApplication=true to be able to type 'reload[ENTER]' when classes are updated");
deployOpenEjbApplication = true;
}
if (!forceReloadable) {
getLog().info("Forcing forceReloadable=true to be able to type 'reload[ENTER]' when classes are updated");
forceReloadable = true;
}
if (docBases == null) {
docBases = new ArrayList<>();
}
if (docBases.isEmpty() && webappResources.exists()) {
getLog().info("adding " + webappResources.toString() + " docBase");
docBases.add(webappResources);
}
if (externalRepositories == null) {
externalRepositories = new ArrayList<>();
}
if (externalRepositories.isEmpty() && webappClasses.exists()) {
getLog().info("adding " + webappClasses.toString() + " externalRepository");
externalRepositories.add(webappClasses);
}
if (systemVariables == null) {
systemVariables = new HashMap<>();
}
if (!systemVariables.containsKey("openejb.classloader.resources.deeper-first")) {
systemVariables.put("openejb.classloader.force-maven", "true");
}
}
private static String filesToString(final Collection files) {
final Collection paths = new ArrayList<>(files.size());
for (final File path : files) { // don't use relative paths (toString())
paths.add(path.getAbsolutePath());
}
return Join.join(",", paths);
}
/**
* Available commands collection.
*
* @return the collection
*/
protected Collection availableCommands() {
return Arrays.asList(QUIT_CMD, EXIT_CMD);
}
/**
* Stop server.
*
* @param stopCondition the stop condition
*/
protected synchronized void stopServer(final CountDownLatch stopCondition) {
if (server == null) {
return;
}
try {
server.stop();
} catch (final Exception e) {
// no-op
}
try {
server.getServer().waitFor();
getLog().info(container + " stopped");
} catch (final Exception e) {
getLog().error("Can't stop " + container, e);
}
server = null;
stopCondition.countDown();
}
private static boolean isQuit(String line) {
if (QUIT_CMD.equalsIgnoreCase(line) || EXIT_CMD.equalsIgnoreCase(line)) {
return true;
}
//http://youtrack.jetbrains.com/issue/IDEA-94826
line = new StringBuilder(line).reverse().toString();
return QUIT_CMD.equalsIgnoreCase(line) || EXIT_CMD.equalsIgnoreCase(line);
}
/**
* Handle line boolean.
*
* @param line the line
* @return the boolean
*/
protected boolean handleLine(final String line) {
return false;
}
/**
* Server cmd.
*
* @param server the server
* @param strings the strings
*/
protected void serverCmd(final RemoteServer server, final List strings) {
try {
server.start(strings, getCmd(), checkStarted);
} catch (final Exception e) {
//TODO - Optional server.destroy()
getLog().warn("Failed to check or track server startup on port: " + this.tomeeHttpPort);
}
}
/**
* Add shutdown hooks.
*
* @param server the server
*/
protected void addShutdownHooks(final RemoteServer server) {
// no-op
}
/**
* Gets connect attempts.
*
* @return the connect attempts
*/
protected int getConnectAttempts() {
return (tomeeShutdownAttempts == 0 ? 60 : tomeeShutdownAttempts);
}
/**
* Gets wait TomEE.
*
* @return the wait TomEE
*/
protected boolean getWaitTomEE() {
return true;
}
private File resolve() {
if (!settings.isOffline()) {
try {
if ("snapshots".equals(apacheRepos) || "true".equals(apacheRepos)) {
remoteRepos.add(new DefaultArtifactRepository("apache", "https://repository.apache.org/content/repositories/snapshots/",
new DefaultRepositoryLayout(),
new ArtifactRepositoryPolicy(true, UPDATE_POLICY_DAILY, CHECKSUM_POLICY_WARN),
new ArtifactRepositoryPolicy(false, UPDATE_POLICY_NEVER, CHECKSUM_POLICY_WARN)));
} else {
try {
new URI(apacheRepos); // to check it is a uri
remoteRepos.add(new DefaultArtifactRepository("additional-repo-tomee-mvn-plugin", apacheRepos,
new DefaultRepositoryLayout(),
new ArtifactRepositoryPolicy(true, UPDATE_POLICY_DAILY, CHECKSUM_POLICY_WARN),
new ArtifactRepositoryPolicy(true, UPDATE_POLICY_NEVER, CHECKSUM_POLICY_WARN)));
} catch (final URISyntaxException e) {
// ignored, use classical repos
}
}
} catch (final UnsupportedOperationException uoe) {
// can happen if remoterepos is unmodifiable (possible in complex builds)
// no-op
}
} else if (remoteRepos != null && remoteRepos.isEmpty()) {
remoteRepos = new ArrayList<>();
}
if ((tomeeClassifier != null && (tomeeClassifier.isEmpty() || tomeeClassifier.equals("ignore")))
|| ("org.apache.tomee".equals(tomeeGroupId) && "openejb-standalone".equals(tomeeArtifactId))) {
tomeeClassifier = null;
}
try {
final Artifact artifact = factory.createDependencyArtifact(tomeeGroupId, tomeeArtifactId, createFromVersion(tomeeVersion), tomeeType, tomeeClassifier, SCOPE_COMPILE);
resolver.resolve(artifact, remoteRepos, local);
return artifact.getFile();
} catch (final Exception e) {
getLog().error(e.getMessage(), e);
throw new TomEEException(e.getMessage(), e);
}
}
private void unzip(final File mvnTomEE) {
ZipFile in = null;
try {
in = new ZipFile(mvnTomEE);
final Enumeration extends ZipEntry> entries = in.entries();
while (entries.hasMoreElements()) {
final ZipEntry entry = entries.nextElement();
String name = entry.getName();
if (skipRootFolderOnUnzip) {
int idx = name.indexOf("/");
if (idx < 0) {
idx = name.indexOf(File.separator);
}
if (idx < 0) {
continue;
}
name = name.substring(idx + 1);
}
final File dest = new File(catalinaBase.getAbsolutePath(), name);
if (!dest.exists()) {
final File parent = dest.getParentFile();
if ((!parent.exists() && !parent.mkdirs())
|| (!parent.canWrite() && !parent.setWritable(true))
|| (!parent.canRead() && !parent.setReadable(true))) {
throw new RuntimeException("Failed to create or set permissions on: " + parent);
}
} else if (!overrideOnUnzip) {
continue;
}
if (entry.isDirectory()) {
if (!dest.exists() && !dest.mkdir()) {
throw new RuntimeException("Failed to create: " + dest);
}
} else {
final FileOutputStream fos = new FileOutputStream(dest);
try {
copy(in.getInputStream(entry), fos);
} catch (final IOException e) {
// ignored
}
close(fos);
if (!dest.canRead() && !dest.setReadable(true)) {
throw new RuntimeException("Failed to set readable on: " + dest);
}
if (dest.getName().endsWith(".sh")) {
if (!dest.canExecute() && !dest.setExecutable(true)) {
throw new RuntimeException("Failed to set executable on: " + dest);
}
}
}
}
File file = new File(catalinaBase, "conf/tomee.xml");
if (file.exists()) {
container = TOM_EE;
} else {
container = "OpenEJB";
file = new File(catalinaBase, "conf/openejb.xml");
if (file.exists()) {
webappDir = "apps";
}
}
ensureAppsFolderExistAndIsConfiguredByDefault(file);
getLog().info(container + " was unzipped in '" + catalinaBase.getAbsolutePath() + "'");
} catch (final Exception e) {
throw new TomEEException(e.getMessage(), e);
} finally {
if (in != null) {
try {
in.close();
} catch (final IOException e) {
// no-op
}
}
}
}
private void ensureAppsFolderExistAndIsConfiguredByDefault(final File file) throws IOException {
if ("openejb".equals(container.toLowerCase(Locale.ENGLISH))
|| (file.exists()
&& (
(apps != null && !apps.isEmpty())
|| (!"pom".equals(packaging) && !"war".equals(packaging))))) { // webapps doesn't need apps folder in tomee
final String rootTag = container.toLowerCase(Locale.ENGLISH);
if (file.isFile()) { // can be not existing since we dont always deploy tomee but shouldn't since then apps/ is not guaranteed to work
try {
final Openejb jaxb = JaxbOpenejb.readConfig(file.getAbsolutePath());
boolean needAdd = true;
for (final Deployments d : jaxb.getDeployments()) {
if ("apps".equals(d.getDir())) {
needAdd = false;
break;
}
}
if (needAdd) {
final String content = IO.slurp(file);
final FileWriter writer = new FileWriter(file);
final String end = "" + rootTag + ">";
writer.write(content.replace(end, " \n" + end));
writer.close();
}
} catch (final OpenEJBException e) {
throw new IllegalStateException("illegal tomee.xml:\n" + IO.slurp(file), e);
}
} else {
final FileWriter writer = new FileWriter(file);
writer.write("\n" +
"<" + rootTag + ">\n" +
" \n" +
"" + rootTag + ">\n");
writer.close();
}
final File appsFolder = new File(catalinaBase, "apps");
if (!appsFolder.exists() && !appsFolder.mkdirs()) {
throw new RuntimeException("Failed to create: " + appsFolder);
}
}
}
private static void doWrite(final File file, final String content) throws IOException {
final FileWriter writer = new FileWriter(file);
try {
writer.write(content);
} finally {
IO.close(writer);
}
}
/**
* Gets cmd.
*
* @return the cmd
*/
public abstract String getCmd();
/**
* The interface Resolver.
*/
public interface Resolver {
/**
* Resolve file.
*
* @param group the group
* @param artifact the artifact
* @param version the version
* @param classifier the classifier
* @param type the type
* @return the file
*/
File resolve(String group, String artifact, String version, String classifier, String type);
/**
* Resolve file.
*
* @param group the group
* @param artifact the artifact
* @param version the version
* @param type the type
* @return the file
*/
File resolve(String group, String artifact, String version, String type);
/**
* Resolve file.
*
* @param group the group
* @param artifact the artifact
* @param version the version
* @return the file
*/
File resolve(String group, String artifact, String version);
}
private static class FileWithMavenMeta {
private final String group;
private final String artifact;
private final String version;
private final String classifier;
private final String type;
private final File resolved;
private FileWithMavenMeta(final String group, final String artifact, final String version,
final String classifier, final String type, final File resolved) {
this.group = group;
this.artifact = artifact;
this.version = version;
this.classifier = classifier;
this.type = type;
this.resolved = resolved;
}
/**
* Strip version string.
*
* @param keepExtension the keep extension
* @return the string
*/
String stripVersion(final boolean keepExtension) {
return artifact + (classifier != null && !classifier.isEmpty() ? "-" + classifier : "") + (keepExtension ? "." + type : "");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy