org.apache.tomee.catalina.deployment.TomcatWebappDeployer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tomee-catalina Show documentation
Show all versions of tomee-catalina Show documentation
This module contains the classes that will be added to the catalina class loader
/*
* 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.tomee.catalina.deployment;
import org.apache.openejb.OpenEJBRuntimeException;
import org.apache.openejb.assembler.WebAppDeployer;
import org.apache.openejb.assembler.classic.AppInfo;
import org.apache.openejb.assembler.classic.DeploymentExceptionManager;
import org.apache.openejb.assembler.classic.WebAppBuilder;
import org.apache.openejb.assembler.classic.WebAppInfo;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
import org.apache.tomee.catalina.TomEERuntimeException;
import org.apache.tomee.catalina.TomcatWebAppBuilder;
import java.io.File;
import java.util.Collection;
import java.util.Iterator;
public class TomcatWebappDeployer implements WebAppDeployer {
private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB, TomcatWebappDeployer.class);
@Override
public AppInfo deploy(final String host, final String context, final File file) {
final TomcatWebAppBuilder tomcatWebAppBuilder = (TomcatWebAppBuilder) SystemInstance.get().getComponent(WebAppBuilder.class);
final Collection alreadyDeployed = tomcatWebAppBuilder.availableApps();
final AppInfo appInfo = fakeInfo(file, host, context);
appInfo.properties.setProperty("tomcat.unpackWar", "false");
try {
tomcatWebAppBuilder.deployWebApps(appInfo, null); // classloader == null -> standalone war
} catch (final Exception e) { // tomcat lost the real exception (only in lifecycle exception string) so try to find it back
final DeploymentExceptionManager dem = SystemInstance.get().getComponent(DeploymentExceptionManager.class);
if (dem != null && dem.hasDeploymentFailed()) {
Throwable lastException = dem.getLastException();
dem.clearLastException(appInfo); // TODO: fix it, since we dont use this appInfo clean is ignored. Not a big deal while dem stores few exceptions only.
if (TomEERuntimeException.class.isInstance(lastException)) {
lastException = TomEERuntimeException.class.cast(lastException).getCause();
}
throw new OpenEJBRuntimeException(Exception.class.cast(lastException));
}
throw new OpenEJBRuntimeException(e);
}
TomcatWebAppBuilder.ContextInfo info = contextInfo(file);
if (info == null) { // try another time doing a diff with apps before deployment and apps after
final Collection deployedNow = tomcatWebAppBuilder.availableApps();
final Iterator it = deployedNow.iterator();
while (it.hasNext()) {
if (alreadyDeployed.contains(it.next())) {
it.remove();
}
}
if (deployedNow.size() == 1) {
info = contextInfo(new File(deployedNow.iterator().next()));
}
}
if (info == null || info.appInfo == null) {
LOGGER.error("Can't find of appInfo for " + (file != null ? file.getAbsolutePath() : null) + ", availables: " + tomcatWebAppBuilder.availableApps());
}
if (info == null) { // error
return null;
}
return info.appInfo;
}
@Override
public void reload(final String path) {
final File file = new File(path);
final TomcatWebAppBuilder.ContextInfo info = contextInfo(file);
if (info == null || info.standardContext == null) { // error
LOGGER.warning("Can't find " + path);
} else {
if (info.standardContext.getReloadable()) {
info.standardContext.reload();
}
}
}
private TomcatWebAppBuilder.ContextInfo contextInfo(final File file) {
final TomcatWebAppBuilder tomcatWebAppBuilder = (TomcatWebAppBuilder) SystemInstance.get().getComponent(WebAppBuilder.class);
return tomcatWebAppBuilder.standaAloneWebAppInfo(file);
}
// simply create a fake AppInfo to be able to deploy reusing the logic we already have
private static AppInfo fakeInfo(final File file, final String host, final String context) {
final AppInfo info = new AppInfo();
info.path = file.getAbsolutePath();
info.webAppAlone = true;
final WebAppInfo webAppInfo = new WebAppInfo();
webAppInfo.path = info.path;
if (context == null) {
webAppInfo.contextRoot = file.getName();
if ("ROOT".equals(webAppInfo.contextRoot)) {
webAppInfo.contextRoot = "";
}
} else {
webAppInfo.contextRoot = context;
}
webAppInfo.host = host; // we don't care if it's null, the default host gonna be used by TomcatWebAppBuilder
webAppInfo.moduleId = webAppInfo.contextRoot;
info.webApps.add(webAppInfo);
return info;
}
}