Repository: tomee Updated Branches: refs/heads/tomee-1.7.x 7e3094233 -> f3dd42b08
TOMEE-2151 create containers using the correct classloader when deploying an EAR file in webapps folder Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/7fa1fc01 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/7fa1fc01 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/7fa1fc01 Branch: refs/heads/tomee-1.7.x Commit: 7fa1fc01eab63b3b1f8cbdf2c302f643fedff2c7 Parents: 7e30942 Author: Jonathan Gallimore <[email protected]> Authored: Mon Dec 4 13:54:38 2017 +0000 Committer: Jonathan Gallimore <[email protected]> Committed: Mon Dec 4 13:54:38 2017 +0000 ---------------------------------------------------------------------- .../openejb/assembler/classic/AppInfo.java | 1 + .../openejb/assembler/classic/Assembler.java | 10 ++ .../apache/openejb/config/AppInfoBuilder.java | 14 +++ .../org/apache/openejb/config/AutoConfig.java | 29 +----- .../apache/openejb/config/ContainerUtils.java | 50 +++++++++ .../moviefun/DeployInWebAppsDirectoryTest.java | 102 ++++++++++++++++--- 6 files changed, 166 insertions(+), 40 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/7fa1fc01/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AppInfo.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AppInfo.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AppInfo.java index e72dd59..fa4153c 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AppInfo.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AppInfo.java @@ -43,6 +43,7 @@ public class AppInfo extends InfoObject { public final List<WebAppInfo> webApps = new ArrayList<WebAppInfo>(); public final List<PersistenceUnitInfo> persistenceUnits = new ArrayList<PersistenceUnitInfo>(); public List<ServiceInfo> services = new ArrayList<ServiceInfo>(); + public List<ContainerInfo> containers = new ArrayList<ContainerInfo>(); public final List<String> libs = new ArrayList<String>(); public final Set<String> watchedResources = new TreeSet<String>(); public final Set<String> containerIds = new TreeSet<String>(); http://git-wip-us.apache.org/repos/asf/tomee/blob/7fa1fc01/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java index 13e690c..a4c967e 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java @@ -744,6 +744,16 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A // This is a conflict we fail to handle. this.checkForDuplicates(appInfo); + final ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(classLoader); + for (final ContainerInfo container : appInfo.containers) { + createContainer(container); + } + } finally { + Thread.currentThread().setContextClassLoader(oldCl); + } + //Construct the global and app jndi contexts for this app final InjectionBuilder injectionBuilder = new InjectionBuilder(classLoader); http://git-wip-us.apache.org/repos/asf/tomee/blob/7fa1fc01/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java b/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java index 73d781c..192a344 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java @@ -24,6 +24,7 @@ import org.apache.openejb.assembler.classic.AppInfo; import org.apache.openejb.assembler.classic.ClassListInfo; import org.apache.openejb.assembler.classic.ClientInfo; import org.apache.openejb.assembler.classic.ConnectorInfo; +import org.apache.openejb.assembler.classic.ContainerInfo; import org.apache.openejb.assembler.classic.EjbJarInfo; import org.apache.openejb.assembler.classic.EnterpriseBeanInfo; import org.apache.openejb.assembler.classic.EntityManagerFactoryCallable; @@ -144,6 +145,7 @@ class AppInfoBuilder { this.buildPojoConfiguration(appModule, appInfo); this.buildAppResources(appModule, appInfo); + this.buildAppContainers(appModule, appInfo); this.buildAppServices(appModule, appInfo); // @@ -365,6 +367,18 @@ class AppInfoBuilder { } } + private void buildAppContainers(final AppModule module, final AppInfo info) throws OpenEJBException { + final List<ContainerInfo> containerInfos = getContainerInfos(module); + if (containerInfos == null) return; + + + info.containers.addAll(containerInfos); + } + + private List<ContainerInfo> getContainerInfos(AppModule module) throws OpenEJBException { + return ContainerUtils.getContainerInfos(module, configFactory); + } + private void buildClientModules(final AppModule appModule, final AppInfo appInfo, final JndiEncInfoBuilder jndiEncInfoBuilder) throws OpenEJBException { for (final ClientModule clientModule : appModule.getClientModules()) { final ApplicationClient applicationClient = clientModule.getApplicationClient(); http://git-wip-us.apache.org/repos/asf/tomee/blob/7fa1fc01/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java b/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java index 5fcf33e..a4505d6 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java @@ -184,16 +184,12 @@ public class AutoConfig implements DynamicDeployer, JndiConstants { @Override public synchronized AppModule deploy(final AppModule appModule) throws OpenEJBException { - final List<ContainerInfo> containerInfos = processApplicationContainers(appModule); + final List<ContainerInfo> containerInfos = ContainerUtils.getContainerInfos(appModule, configFactory); final AppResources appResources = new AppResources(appModule, containerInfos); appResources.dump(); processApplicationResources(appModule); - for (final ContainerInfo containerInfo : containerInfos) { - configFactory.install(containerInfo); - } - for (final EjbModule ejbModule : appModule.getEjbModules()) { processActivationConfig(ejbModule); } @@ -893,29 +889,6 @@ public class AutoConfig implements DynamicDeployer, JndiConstants { } } - private List<ContainerInfo> processApplicationContainers(final AppModule module) throws OpenEJBException { - if (module.getContainers().isEmpty()) { - return Collections.emptyList(); - } - - final List<ContainerInfo> containerInfos = new ArrayList<ContainerInfo>(); - - final String prefix = module.getModuleId() + "/"; - for (final Container container : module.getContainers()) { - if (container.getId() == null) { - throw new IllegalStateException("a container can't get a null id: " + container.getType() + " from " + module.getModuleId()); - } - if (!container.getId().startsWith(prefix)) { - container.setId(prefix + container.getId()); - } - final ContainerInfo containerInfo = configFactory.createContainerInfo(container); - containerInfo.originAppName = module.getModuleId(); - containerInfos.add(containerInfo); - } - - return containerInfos; - } - private void processApplicationResources(final AppModule module) throws OpenEJBException { final Collection<Resource> resources = module.getResources(); http://git-wip-us.apache.org/repos/asf/tomee/blob/7fa1fc01/container/openejb-core/src/main/java/org/apache/openejb/config/ContainerUtils.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/ContainerUtils.java b/container/openejb-core/src/main/java/org/apache/openejb/config/ContainerUtils.java new file mode 100644 index 0000000..09bfd54 --- /dev/null +++ b/container/openejb-core/src/main/java/org/apache/openejb/config/ContainerUtils.java @@ -0,0 +1,50 @@ +/* + * 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.config; + +import org.apache.openejb.OpenEJBException; +import org.apache.openejb.assembler.classic.ContainerInfo; +import org.apache.openejb.config.sys.Container; + +import java.util.ArrayList; +import java.util.List; + +public class ContainerUtils { + public static List<ContainerInfo> getContainerInfos(final AppModule module, final ConfigurationFactory configFactory) throws OpenEJBException { + final List<ContainerInfo> containerInfos = new ArrayList<ContainerInfo>(); + if (module.getContainers().isEmpty()) { + return containerInfos; + } + + final String prefix = module.getModuleId() + "/"; + for (final Container container : module.getContainers()) { + if (container.getId() == null) { + throw new IllegalStateException("a container can't get a null id: " + container.getType() + " from " + module.getModuleId()); + } + if (!container.getId().startsWith(prefix)) { + container.setId(prefix + container.getId()); + } + + final ContainerInfo containerInfo = configFactory.createContainerInfo(container); + containerInfo.originAppName = module.getModuleId(); + containerInfos.add(containerInfo); + } + + return containerInfos; + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/7fa1fc01/examples/connector-ear/connector-sample-functional-tests/src/test/java/org/superbiz/moviefun/DeployInWebAppsDirectoryTest.java ---------------------------------------------------------------------- diff --git a/examples/connector-ear/connector-sample-functional-tests/src/test/java/org/superbiz/moviefun/DeployInWebAppsDirectoryTest.java b/examples/connector-ear/connector-sample-functional-tests/src/test/java/org/superbiz/moviefun/DeployInWebAppsDirectoryTest.java index 3666124..74c387e 100644 --- a/examples/connector-ear/connector-sample-functional-tests/src/test/java/org/superbiz/moviefun/DeployInWebAppsDirectoryTest.java +++ b/examples/connector-ear/connector-sample-functional-tests/src/test/java/org/superbiz/moviefun/DeployInWebAppsDirectoryTest.java @@ -16,20 +16,30 @@ */ package org.superbiz.moviefun; +import org.apache.cxf.jaxrs.client.WebClient; import org.apache.openejb.loader.IO; import org.apache.tomee.arquillian.remote.RemoteTomEEConfiguration; import org.apache.tomee.arquillian.remote.RemoteTomEEContainer; -import org.jboss.shrinkwrap.resolver.api.maven.Maven; -import org.junit.Ignore; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.exporter.ZipExporter; +import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.jboss.shrinkwrap.api.spec.ResourceAdapterArchive; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.shrinkwrap.descriptor.api.Descriptors; +import org.jboss.shrinkwrap.descriptor.api.application6.ApplicationDescriptor; +import org.jboss.shrinkwrap.descriptor.api.webapp30.WebAppDescriptor; import org.junit.Test; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.io.File; -import java.io.IOException; +import java.io.InputStream; import java.util.concurrent.Callable; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; -@Ignore("Not implemented yet") /* * This test deploys the ear in a manual fashion. Normally the remote adapter deploys using the deployer. * Here we'll use the arquillian adapter to control the lifecycle of the server, but we'll do the deploy @@ -38,13 +48,65 @@ import static org.junit.Assert.assertTrue; */ public class DeployInWebAppsDirectoryTest { + public static EnterpriseArchive createDeployment() { + + final JavaArchive apiJar = ShrinkWrap.create(JavaArchive.class, "connector-sample-api.jar"); + apiJar.addPackage("org.superbiz.connector.api"); + System.out.println("API JAR:\n" + apiJar.toString(true)); + + final JavaArchive implJar = ShrinkWrap.create(JavaArchive.class, "connector-sample-impl.jar"); + implJar.addPackage("org.superbiz.connector.adapter"); + System.out.println("IMPL JAR:\n" + implJar.toString(true)); + + final ResourceAdapterArchive rar = ShrinkWrap.create(ResourceAdapterArchive.class,"connector-sample-ra.rar"); + rar.addAsLibraries(implJar); + + final File raXml = Basedir.basedir("../connector-sample-rar/src/main/rar/META-INF/ra.xml"); + rar.setResourceAdapterXML(raXml); + System.out.println("RAR:\n" + rar.toString(true)); + + final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "connector-sample-war.war"); + webArchive.addPackage("org.superbiz.application"); + + final WebAppDescriptor webAppDescriptor = Descriptors.create(WebAppDescriptor.class); + webAppDescriptor.version("3.0"); + + final File resourcesXml = Basedir.basedir("../connector-sample-war/src/main/webapp/WEB-INF/resources.xml"); + webArchive.addAsWebInfResource(resourcesXml); + webArchive.setWebXML(new StringAsset(webAppDescriptor.exportAsString())); + webArchive.addAsWebInfResource(resourcesXml); + webArchive.addAsWebInfResource(new StringAsset("<beans/>"), "beans.xml"); + System.out.println("Webapp:\n" + webArchive.toString(true)); + + final EnterpriseArchive enterpriseArchive = ShrinkWrap.create(EnterpriseArchive.class, "connector-sample.ear"); + enterpriseArchive.addAsLibraries(apiJar); + enterpriseArchive.addAsModule(rar); + enterpriseArchive.addAsModule(webArchive); + + ApplicationDescriptor applicationXml = Descriptors.create(ApplicationDescriptor.class); + applicationXml.displayName("connector-sample-ear"); + applicationXml.createModule() + .getOrCreateWeb() + .webUri("connector-sample-war.war") + .contextRoot("/sample") + .up().up() + .createModule().connector("connector-sample-ra.rar") + .up().libraryDirectory("lib"); + + enterpriseArchive.setApplicationXML(new StringAsset(applicationXml.exportAsString())); + System.out.println(enterpriseArchive.toString(true)); + + return enterpriseArchive; + } + @Test public void test() throws Exception { final RemoteTomEEConfiguration configuration = new RemoteTomEEConfiguration(); configuration.setGroupId("org.apache.openejb"); configuration.setArtifactId("apache-tomee"); configuration.setClassifier("plus"); - configuration.setVersion("1.7.5-SNAPSHOT"); + configuration.setVersion("1.7.6-SNAPSHOT"); +// configuration.setDebug(true); configuration.setHttpPort(-1); final RemoteTomEEContainer container = new RemoteTomEEContainer(); @@ -56,13 +118,19 @@ public class DeployInWebAppsDirectoryTest { final File webapps = new File(configuration.getDir(), "apache-tomee-" + configuration.getClassifier() + "-" + configuration.getVersion() + "/webapps"); webapps.mkdirs(); - final File enterpriseArchive = Maven.resolver().resolve("org.superbiz:moviefun-ear:ear:1.1.0-SNAPSHOT") - .withoutTransitivity().asSingleFile(); + final InputStream is = createDeployment().as(ZipExporter.class).exportAsInputStream(); - IO.copy(enterpriseArchive, new File(webapps, "moviefun-ear.ear")); - final String appUrl = "http://localhost:" + configuration.getHttpPort() + "/moviefun"; + IO.copy(is, new File(webapps, "connector-sample.ear")); + final String appUrl = "http://localhost:" + configuration.getHttpPort() + "/sample/"; -// runTests(appUrl); + attempt(new Callable<Void>() { + + @Override + public Void call() throws Exception { + runTests(appUrl); + return null; + } + }, 30); container.stop(); @@ -74,13 +142,23 @@ public class DeployInWebAppsDirectoryTest { } } + public void runTests(final String appUrl) throws Exception { + final WebClient webClient = WebClient.create(appUrl); + final Response response = webClient.path("").type(MediaType.TEXT_PLAIN_TYPE).post("Hello, world"); + + assertEquals(204, response.getStatus()); + final String result = webClient.path("").accept(MediaType.TEXT_PLAIN_TYPE).get(String.class); + + assertEquals("Hello, world", result); + } + private <T> T attempt(final Callable<T> callable, int numberOfAttempts) { int tries = 0; while (tries < numberOfAttempts) { try { return callable.call(); - } catch (final Exception e) { + } catch (final Throwable e) { // ignore the exception and try again tries++; try {
