Author: rmannibucau Date: Mon Sep 22 18:50:05 2014 New Revision: 1626869 URL: http://svn.apache.org/r1626869 Log: TOMEE-1355 just providing a deployclasspath method in embedded container is enough, we don't need to describe the app in EE since we always scan
Added: tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/internal/ tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/internal/StandardContextCustomizer.java - copied, changed from r1626577, tomee/tomee/trunk/tomee/tomee-application-composer/src/main/java/org/apache/tomee/application/composer/internal/StandardContextCustomizer.java tomee/tomee/trunk/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/ClasspathAsWebappTest.java tomee/tomee/trunk/tomee/tomee-embedded/src/test/resources/META-INF/services/ tomee/tomee/trunk/tomee/tomee-embedded/src/test/resources/META-INF/services/javax.servlet.ServletContainerInitializer Removed: tomee/tomee/trunk/tomee/tomee-application-composer/ Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/NewLoaderLogic.java tomee/tomee/trunk/tomee/pom.xml tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java tomee/tomee/trunk/tomee/tomee-embedded/pom.xml tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Configuration.java tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java?rev=1626869&r1=1626868&r2=1626869&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java Mon Sep 22 18:50:05 2014 @@ -5421,8 +5421,10 @@ public class AnnotationDeployer implemen public static boolean isInstantiable(final Class<?> clazz) { final int modifiers = clazz.getModifiers(); - return !Modifier.isAbstract(modifiers) && !(clazz.getEnclosingClass() != null && !Modifier.isStatic(modifiers)) - && Modifier.isPublic(modifiers); + return !Modifier.isAbstract(modifiers) + && !(clazz.getEnclosingClass() != null + && !Modifier.isStatic(modifiers)) + && Modifier.isPublic(modifiers) && !clazz.isEnum(); } private static boolean isEJB(final Class<?> clazz) { Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/NewLoaderLogic.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/NewLoaderLogic.java?rev=1626869&r1=1626868&r2=1626869&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/NewLoaderLogic.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/NewLoaderLogic.java Mon Sep 22 18:50:05 2014 @@ -86,6 +86,10 @@ public class NewLoaderLogic { } public static Set<String> callers() { + return callers(Filters.classes("javax.ejb.embeddable.EJBContainer", "javax.naming.InitialContext")); + } + + public static Set<String> callers(final Filter start) { final Set<String> callers = new LinkedHashSet<String>(); @@ -94,9 +98,6 @@ public class NewLoaderLogic { // Yank out everything until we find a known ENTRY point // if we don't find one, so be it, this is only a convenience { - // Entry points are the following: - final Filter start = Filters.classes("javax.ejb.embeddable.EJBContainer", "javax.naming.InitialContext"); - final Iterator<StackTraceElement> iterator = elements.iterator(); while (iterator.hasNext()) { final StackTraceElement element = iterator.next(); Modified: tomee/tomee/trunk/tomee/pom.xml URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/pom.xml?rev=1626869&r1=1626868&r2=1626869&view=diff ============================================================================== --- tomee/tomee/trunk/tomee/pom.xml (original) +++ tomee/tomee/trunk/tomee/pom.xml Mon Sep 22 18:50:05 2014 @@ -55,7 +55,6 @@ <module>tomee-util</module> <module>tomee-juli</module> <module>tomee-overlay-runner</module> - <module>tomee-application-composer</module> <!--<module>tomee-deb</module>--> </modules> Modified: tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java?rev=1626869&r1=1626868&r2=1626869&view=diff ============================================================================== --- tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java (original) +++ tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java Mon Sep 22 18:50:05 2014 @@ -1149,22 +1149,7 @@ public class TomcatWebAppBuilder impleme } } - OpenEJBContextConfig openEJBContextConfig = null; - for (final LifecycleListener listener : standardContext.findLifecycleListeners()) { - if (OpenEJBContextConfig.class.isInstance(listener)) { - openEJBContextConfig = OpenEJBContextConfig.class.cast(listener); - break; - } - } - if (openEJBContextConfig != null) { - for (final EjbModule ejbModule : appModule.getEjbModules()) { - if (ejbModule.getFile() != null && warPath(standardContext).equals(rootPath(ejbModule.getFile()))) { - openEJBContextConfig.finder(ejbModule.getFinder(), ejbModule.getClassLoader()); - break; - } - } - } - + setFinderOnContextConfig(standardContext, appModule); appContext = a.createApplication(contextInfo.appInfo, classLoader); // todo add watched resources to context @@ -1330,6 +1315,24 @@ public class TomcatWebAppBuilder impleme realms.put(standardContext.getName(), realm); } + public void setFinderOnContextConfig(final StandardContext standardContext, final AppModule appModule) { + OpenEJBContextConfig openEJBContextConfig = null; + for (final LifecycleListener listener : standardContext.findLifecycleListeners()) { + if (OpenEJBContextConfig.class.isInstance(listener)) { + openEJBContextConfig = OpenEJBContextConfig.class.cast(listener); + break; + } + } + if (openEJBContextConfig != null) { + for (final EjbModule ejbModule : appModule.getEjbModules()) { + if (ejbModule.getFile() != null && warPath(standardContext).equals(rootPath(ejbModule.getFile()))) { + openEJBContextConfig.finder(ejbModule.getFinder(), ejbModule.getClassLoader()); + break; + } + } + } + } + private static File rootPath(final File file) { if (file.isDirectory() && file.getName().equals("classes") && file.getParentFile() != null && file.getParentFile().getName().equals("WEB-INF")) { return file.getParentFile().getParentFile(); Modified: tomee/tomee/trunk/tomee/tomee-embedded/pom.xml URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-embedded/pom.xml?rev=1626869&r1=1626868&r2=1626869&view=diff ============================================================================== --- tomee/tomee/trunk/tomee/tomee-embedded/pom.xml (original) +++ tomee/tomee/trunk/tomee/tomee-embedded/pom.xml Mon Sep 22 18:50:05 2014 @@ -96,6 +96,11 @@ <classifier>tomcat</classifier> </dependency> <dependency> + <groupId>org.apache.tomcat</groupId> + <artifactId>tomcat-websocket-api</artifactId> + <version>${tomcat.version}</version> + </dependency> + <dependency> <groupId>org.apache.openejb</groupId> <artifactId>tomee-myfaces</artifactId> <version>${project.version}</version> @@ -247,6 +252,16 @@ </exclusion> </exclusions> </dependency> + <dependency> <!-- now in webprofile --> + <groupId>org.apache.openejb</groupId> + <artifactId>tomee-jaxrs</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.tomcat</groupId> + <artifactId>tomcat-websocket</artifactId> + <version>${tomcat.version}</version> + </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> Modified: tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Configuration.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Configuration.java?rev=1626869&r1=1626868&r2=1626869&view=diff ============================================================================== --- tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Configuration.java (original) +++ tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Configuration.java Mon Sep 22 18:50:05 2014 @@ -44,6 +44,13 @@ public class Configuration { private String keyAlias; private String sslProtocol; + private boolean deployOpenEjbApp = false; + + /** + * when needed temp file only (deployClasspathAsWebapp() for instance) + */ + private String tempDir = new File(System.getProperty("java.io.tmpdir"), "tomee-embedded_" + System.currentTimeMillis()).getAbsolutePath(); + public int getHttpPort() { return httpPort; } @@ -195,4 +202,25 @@ public class Configuration { properties.setProperty(key, value); return this; } + + public String getTempDir() { + return tempDir; + } + + public void setTempDir(final String tempDir) { + this.tempDir = tempDir; + } + + public boolean isDeployOpenEjbApp() { + return deployOpenEjbApp; + } + + public void setDeployOpenEjbApp(final boolean deployOpenEjbApp) { + this.deployOpenEjbApp = deployOpenEjbApp; + } + + public Configuration http(final int port) { + setHttpPort(port); + return this; + } } Modified: tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java?rev=1626869&r1=1626868&r2=1626869&view=diff ============================================================================== --- tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java (original) +++ tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java Mon Sep 22 18:50:05 2014 @@ -28,6 +28,7 @@ import org.apache.catalina.startup.Tomca import org.apache.coyote.http11.Http11Protocol; import org.apache.openejb.AppContext; import org.apache.openejb.BeanContext; +import org.apache.openejb.Injector; import org.apache.openejb.NoSuchApplicationException; import org.apache.openejb.OpenEJB; import org.apache.openejb.OpenEJBException; @@ -38,21 +39,40 @@ import org.apache.openejb.assembler.clas import org.apache.openejb.assembler.classic.EjbJarInfo; import org.apache.openejb.assembler.classic.EnterpriseBeanInfo; import org.apache.openejb.assembler.classic.WebAppInfo; +import org.apache.openejb.config.AnnotationDeployer; +import org.apache.openejb.config.AppModule; import org.apache.openejb.config.ConfigurationFactory; +import org.apache.openejb.config.DeploymentLoader; +import org.apache.openejb.config.DeploymentsResolver; +import org.apache.openejb.config.EjbModule; +import org.apache.openejb.config.FinderFactory; +import org.apache.openejb.config.NewLoaderLogic; +import org.apache.openejb.config.WebModule; +import org.apache.openejb.jee.Beans; +import org.apache.openejb.jee.EjbJar; +import org.apache.openejb.jee.ManagedBean; +import org.apache.openejb.jee.TransactionType; +import org.apache.openejb.jee.WebApp; +import org.apache.openejb.jee.oejb3.EjbDeployment; +import org.apache.openejb.jee.oejb3.OpenejbJar; import org.apache.openejb.loader.Files; import org.apache.openejb.loader.IO; import org.apache.openejb.loader.SystemInstance; +import org.apache.openejb.loader.provisining.ProvisioningResolver; import org.apache.openejb.spi.ContainerSystem; import org.apache.openejb.util.LogCategory; import org.apache.openejb.util.Logger; import org.apache.tomee.catalina.TomEERuntimeException; import org.apache.tomee.catalina.TomcatLoader; import org.apache.tomee.catalina.session.FastNonSecureRandom; +import org.apache.tomee.embedded.internal.StandardContextCustomizer; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; +import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.log.NullLogChute; import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; +import org.apache.xbean.finder.filter.Filters; import javax.naming.Context; import javax.naming.NamingException; @@ -62,9 +82,14 @@ import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.Writer; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; import java.util.concurrent.CountDownLatch; /** @@ -86,9 +111,13 @@ public class Container implements AutoCl private Tomcat tomcat; // start the container directly - public Container(final Configuration configuration) throws Exception { + public Container(final Configuration configuration) { setup(configuration); - start(); + try { + start(); + } catch (final Exception e) { + throw new IllegalStateException(e); + } } public Container() { @@ -97,6 +126,108 @@ public class Container implements AutoCl this.configuration.setStopPort(23881); } + public Container deployClasspathAsWebApp() { + return deployClasspathAsWebApp(""); + } + + public Container deployClasspathAsWebApp(final String context, final String... dependencies) { + final List<URL> jarList = DeploymentsResolver.loadFromClasspath(Thread.currentThread().getContextClassLoader()); + if (dependencies != null) { + for (final String dep : dependencies) { + final Set<String> strings = SystemInstance.get().getComponent(ProvisioningResolver.class).realLocation(dep); + for (final String path : strings) { + try { + jarList.add(new File(path).toURI().toURL()); + } catch (final MalformedURLException e) { + throw new IllegalArgumentException(e); + } + } + } + } + + return deployPathsAsWebapp(context, jarList); + } + + public Container deployPathsAsWebapp(final String context, final List<URL> jarList) { + final ClassLoader loader = Thread.currentThread().getContextClassLoader(); + final SystemInstance systemInstance = SystemInstance.get(); + + String contextRoot = context == null ? "" : context; + if (!contextRoot.isEmpty() && !contextRoot.startsWith("/")) { + contextRoot = "/" + context; + } + + final WebModule webModule = new WebModule(new WebApp(), contextRoot, loader, fakeRootDir().getAbsolutePath(), contextRoot); + webModule.setUrls(jarList); + webModule.setAddedUrls(Collections.<URL>emptyList()); + webModule.setRarUrls(Collections.<URL>emptyList()); + webModule.setScannableUrls(jarList); + try { + webModule.setFinder(FinderFactory.createFinder(webModule)); + } catch (final Exception e) { + throw new IllegalArgumentException(e); + } + + DeploymentLoader.addBeansXmls(webModule); + + final AppModule app = new AppModule(loader, null); + app.setStandloneWebModule(); + try { + DeploymentLoader.addWebModule(webModule, app); + } catch (final OpenEJBException e) { + throw new IllegalStateException(e); + } + + addCallersAsEjbModule(loader, app); + + systemInstance.addObserver(new StandardContextCustomizer(webModule)); + + try { + final AppInfo appInfo = configurationFactory.configureApplication(app); + systemInstance.getComponent(Assembler.class).createApplication(appInfo); + } catch (final Exception e) { + throw new IllegalStateException(e); + } + + return this; + } + + private static void addCallersAsEjbModule(final ClassLoader loader, final AppModule app) { + final Set<String> callers = NewLoaderLogic.callers(Filters.classes(Container.class.getName())); + if (callers.isEmpty()) { + return; + } + final EjbJar ejbJar = new EjbJar(); + final OpenejbJar openejbJar = new OpenejbJar(); + + for (final String caller : callers) { + try { + if (!AnnotationDeployer.isInstantiable(loader.loadClass(caller))) { + continue; + } + } catch (final ClassNotFoundException e) { + continue; + } + + final String name = caller.replace("$", "_"); + final ManagedBean bean = ejbJar.addEnterpriseBean(new ManagedBean(caller.replace("$", "_"), caller, true)); + bean.localBean(); + bean.setTransactionType(TransactionType.BEAN); + final EjbDeployment ejbDeployment = openejbJar.addEjbDeployment(bean); + ejbDeployment.setDeploymentId(name); + } + final EjbModule ejbModule = new EjbModule(ejbJar, openejbJar); + ejbModule.setBeans(new Beans()); + app.getEjbModules().add(ejbModule); + } + + private File fakeRootDir() { + final File root = new File(configuration.getTempDir()); + Files.mkdirs(root); + Files.deleteOnExit(root); + return root; + } + private static boolean sameApplication(final File file, final WebAppInfo webApp) { String filename = file.getName(); if (filename.endsWith(".war")) { @@ -327,7 +458,7 @@ public class Container implements AutoCl file = File.createTempFile("apache-tomee", "-home", target.exists() ? target : null); } catch (final Exception e) { - final File tmp = new File("tmp"); + final File tmp = new File(configuration.getTempDir()); if (!tmp.exists() && !tmp.mkdirs()) { throw new IOException("Failed to create local tmp directory: " + tmp.getAbsolutePath()); } @@ -488,12 +619,14 @@ public class Container implements AutoCl } private void copyTemplateTo(final File targetDir, final String filename) throws Exception { - Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, new NullLogChute()); - Velocity.setProperty(Velocity.RESOURCE_LOADER, "class"); - Velocity.setProperty("class.resource.loader.description", "Velocity Classpath Resource Loader"); - Velocity.setProperty("class.resource.loader.class", ClasspathResourceLoader.class.getName()); - Velocity.init(); - final Template template = Velocity.getTemplate("/org/apache/tomee/configs/" + filename); + // don't break apps using Velocity facade + final VelocityEngine engine = new VelocityEngine(); + engine.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, new NullLogChute()); + engine.setProperty(Velocity.RESOURCE_LOADER, "class"); + engine.setProperty("class.resource.loader.description", "Velocity Classpath Resource Loader"); + engine.setProperty("class.resource.loader.class", ClasspathResourceLoader.class.getName()); + engine.init(); + final Template template = engine.getTemplate("/org/apache/tomee/configs/" + filename); final VelocityContext context = new VelocityContext(); context.put("tomcatHttpPort", Integer.toString(configuration.getHttpPort())); context.put("tomcatShutdownPort", Integer.toString(configuration.getStopPort())); @@ -532,7 +665,7 @@ public class Container implements AutoCl } @Override - public void close() throws IOException { + public void close() { final CountDownLatch end = new CountDownLatch(1); final Container container = Container.this; new Thread() { @@ -554,7 +687,7 @@ public class Container implements AutoCl try { stop(); } catch (final Exception e) { - throw new IOException("Failed to stop container", e); + throw new IllegalStateException("Failed to stop container", e); } try { @@ -572,6 +705,15 @@ public class Container implements AutoCl return getTomcat().addContext(context, root.getAbsolutePath()); // we don't want to be relative } + public Container inject(final Object instance) { + Injector.inject(instance); + return this; + } + + public Configuration getConfiguration() { + return configuration; + } + private static class TomcatWithFastSessionIDs extends Tomcat { @Override Copied: tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/internal/StandardContextCustomizer.java (from r1626577, tomee/tomee/trunk/tomee/tomee-application-composer/src/main/java/org/apache/tomee/application/composer/internal/StandardContextCustomizer.java) URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/internal/StandardContextCustomizer.java?p2=tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/internal/StandardContextCustomizer.java&p1=tomee/tomee/trunk/tomee/tomee-application-composer/src/main/java/org/apache/tomee/application/composer/internal/StandardContextCustomizer.java&r1=1626577&r2=1626869&rev=1626869&view=diff ============================================================================== --- tomee/tomee/trunk/tomee/tomee-application-composer/src/main/java/org/apache/tomee/application/composer/internal/StandardContextCustomizer.java (original) +++ tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/internal/StandardContextCustomizer.java Mon Sep 22 18:50:05 2014 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.tomee.application.composer.internal; +package org.apache.tomee.embedded.internal; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; @@ -24,27 +24,24 @@ import org.apache.catalina.WebResourceRo import org.apache.catalina.core.StandardContext; import org.apache.catalina.webresources.StandardRoot; import org.apache.openejb.config.WebModule; +import org.apache.openejb.loader.SystemInstance; import org.apache.openejb.observer.Observes; import org.apache.openejb.util.URLs; +import org.apache.tomee.catalina.TomcatWebAppBuilder; import java.io.File; import java.net.URL; public class StandardContextCustomizer { private final WebModule module; - private boolean enriched = false; public StandardContextCustomizer(final WebModule webModule) { module = webModule; } public void customize(final @Observes LifecycleEvent event) { - if (enriched) { - return; - } - final Object data = event.getSource(); - if (!StandardContext.class.isInstance(data) || !Lifecycle.BEFORE_START_EVENT.equals(event.getType())) { + if (!StandardContext.class.isInstance(data)) { return; } @@ -52,18 +49,25 @@ public class StandardContextCustomizer { if (!module.getContextRoot().equals(context.getPath())) { return; } - context.setResources(new StandardRoot(context)); - final WebResourceRoot resources = context.getResources(); - for (final URL url : module.getScannableUrls()) { - final File file = URLs.toFile(url); - if (file.isDirectory()) { - resources.createWebResourceSet(WebResourceRoot.ResourceSetType.RESOURCE_JAR, "/WEB-INF/classes", file.getAbsolutePath(), "", "/"); - } else { - resources.createWebResourceSet(WebResourceRoot.ResourceSetType.RESOURCE_JAR, "/WEB-INF/lib", file.getAbsolutePath(), "", "/"); - } + switch (event.getType()) { + case Lifecycle.BEFORE_START_EVENT: + context.setResources(new StandardRoot(context)); + + final WebResourceRoot resources = context.getResources(); + for (final URL url : module.getScannableUrls()) { + final File file = URLs.toFile(url); + if (file.isDirectory()) { + resources.createWebResourceSet(WebResourceRoot.ResourceSetType.RESOURCE_JAR, "/WEB-INF/classes", file.getAbsolutePath(), "", "/"); + } else { + resources.createWebResourceSet(WebResourceRoot.ResourceSetType.RESOURCE_JAR, "/WEB-INF/lib", file.getAbsolutePath(), "", "/"); + } + } + break; + case Lifecycle.CONFIGURE_START_EVENT: + SystemInstance.get().getComponent(TomcatWebAppBuilder.class).setFinderOnContextConfig(StandardContext.class.cast(data), module.appModule()); + break; + default: } - - enriched = true; } } Added: tomee/tomee/trunk/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/ClasspathAsWebappTest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/ClasspathAsWebappTest.java?rev=1626869&view=auto ============================================================================== --- tomee/tomee/trunk/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/ClasspathAsWebappTest.java (added) +++ tomee/tomee/trunk/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/ClasspathAsWebappTest.java Mon Sep 22 18:50:05 2014 @@ -0,0 +1,211 @@ +/** + * 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.embedded; + +import org.apache.openejb.loader.IO; +import org.apache.openejb.loader.JarLocation; +import org.apache.openejb.util.NetworkUtil; +import org.junit.Test; + +import javax.ejb.EJB; +import javax.ejb.Singleton; +import javax.inject.Inject; +import javax.servlet.ServletContainerInitializer; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.annotation.HandlesTypes; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.websocket.ClientEndpoint; +import javax.websocket.CloseReason; +import javax.websocket.ContainerProvider; +import javax.websocket.DeploymentException; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; +import javax.websocket.server.ServerEndpoint; +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.Application; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +public class ClasspathAsWebappTest { + @Inject + private MyBean bean; + + @EJB + private Task2 anEjb; + + @Test + public void run() throws MalformedURLException { + MyInitializer.found = null; + MyBean.VALUE = null; + try (final Container container = new Container( + new Configuration().http(NetworkUtil.getNextAvailablePort())) + .deployPathsAsWebapp("", asList(JarLocation.jarLocation(MyInitializer.class).toURI().toURL())) + .inject(this)) { + + // Servlet (initializer, servlet) + assertNotNull(MyInitializer.found); + assertEquals(1, MyInitializer.found.size()); + assertEquals(Task1.class, MyInitializer.found.iterator().next()); + try { + assertEquals("Servlet!", IO.slurp(new URL("http://localhost:" + container.getConfiguration().getHttpPort() + "/s"))); + } catch (final IOException e) { + fail(e.getMessage()); + } + try { + assertEquals("WebServlet", IO.slurp(new URL("http://localhost:" + container.getConfiguration().getHttpPort() + "/w"))); + } catch (final IOException e) { + fail(e.getMessage()); + } + + // CDI + assertNotNull(bean); + assertNull(bean.value()); + MyBean.VALUE = "cdi"; + assertEquals("cdi", bean.value()); + + // EJB + MyBean.VALUE = "ejb"; + assertEquals("ejb", anEjb.run()); + + // JAXRS + try { + assertEquals("jaxrs", IO.slurp(new URL("http://localhost:" + container.getConfiguration().getHttpPort() + "/api/resource"))); + } catch (final IOException e) { + fail(e.getMessage()); + } + + // WebSocket + final WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer(); + try { + WebSocketClient.message = null; + final WebSocketClient webSocketClient = new WebSocketClient(); + final Session session = webSocketContainer.connectToServer(webSocketClient, new URI("ws://localhost:" + container.getConfiguration().getHttpPort() + "/ws")); + webSocketClient.latch.await(20, TimeUnit.SECONDS); + session.close(); + assertEquals("websocket", WebSocketClient.message); + } catch (final Exception e) { + fail(e.getMessage()); + } + } + } + + @ClientEndpoint + public static class WebSocketClient { + private static String message; + private final CountDownLatch latch = new CountDownLatch(1); + + @OnMessage + public void onMessage(final String msg) { + message = msg; + latch.countDown(); + } + } + + @ServerEndpoint("/ws") + public static class WebSocketEndpoint { + @OnOpen + public void open(final Session session) { + try { + session.getBasicRemote().sendText("websocket"); + } catch (IOException e) { + try { + session.close(new CloseReason(CloseReason.CloseCodes.PROTOCOL_ERROR, "Should be able to send a message")); + } catch (final IOException e1) { + throw new IllegalStateException(e1); + } + } + } + } + + @ApplicationPath("api") + public static class App extends Application { + } + + @Path("resource") + public static class Resource { + @GET + public String t() { + return "jaxrs"; + } + } + + @WebServlet(urlPatterns = "/w") + public static class MyWebServlet extends HttpServlet { + @Override + protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { + resp.getWriter().write("WebServlet"); + } + } + + @HandlesTypes(Runnable.class) + public static class MyInitializer implements ServletContainerInitializer { + private static Set<Class<?>> found; + + @Override + public void onStartup(final Set<Class<?>> c, final ServletContext ctx) throws ServletException { + found = c; + ctx.addServlet("s", new HttpServlet() { + @Override + protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { + resp.getWriter().write("Servlet!"); + } + }).addMapping("/s"); + } + } + + public static class Task1 implements Runnable { + @Override + public void run() { + // no-op + } + } + + @Singleton + public static class Task2 { + public String run() { + return MyBean.VALUE; + } + } + + public static class MyBean { + private static volatile String VALUE; + + public String value() { + return VALUE; + } + } +} Added: tomee/tomee/trunk/tomee/tomee-embedded/src/test/resources/META-INF/services/javax.servlet.ServletContainerInitializer URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-embedded/src/test/resources/META-INF/services/javax.servlet.ServletContainerInitializer?rev=1626869&view=auto ============================================================================== --- tomee/tomee/trunk/tomee/tomee-embedded/src/test/resources/META-INF/services/javax.servlet.ServletContainerInitializer (added) +++ tomee/tomee/trunk/tomee/tomee-embedded/src/test/resources/META-INF/services/javax.servlet.ServletContainerInitializer Mon Sep 22 18:50:05 2014 @@ -0,0 +1 @@ +org.apache.tomee.embedded.ClasspathAsWebappTest$MyInitializer