cleaning up SequenceData in assembler is surely more appropriated + fixing test to know if we have a request in CdiAppContextsService + quick enhancement for ScanJarService to support folder
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/51e9d77d Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/51e9d77d Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/51e9d77d Branch: refs/heads/master Commit: 51e9d77d2fa6a0be68de50be59e82a7d4ed6b99a Parents: 536d1c5 Author: Romain Manni-Bucau <[email protected]> Authored: Fri Mar 6 15:51:11 2015 +0100 Committer: Romain Manni-Bucau <[email protected]> Committed: Fri Mar 6 15:51:38 2015 +0100 ---------------------------------------------------------------------- .../openejb/cdi/CdiAppContextsService.java | 3 +- .../apache/openejb/service/ScanJarService.java | 173 +++++++++++++------ tck/cdi-embedded/pom.xml | 1 + .../tck/cdi/embedded/CleanUpAssembler.java | 30 ++++ .../tck/cdi/embedded/StandaloneTckCleaner.java | 34 ---- tck/cdi-embedded/src/test/resources/failing.xml | 2 +- tck/cdi-embedded/src/test/resources/passing.xml | 1 - 7 files changed, 154 insertions(+), 90 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/51e9d77d/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java b/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java index d9067db..3e352a3 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java @@ -539,7 +539,8 @@ public class CdiAppContextsService extends AbstractContextsService implements Co final SessionContext context = sessionContext.get(); if (context != null && context.isActive()) { - if (getRequestContext(false) == null) { + final ServletRequestContext servletRequestContext = getRequestContext(false); + if (servletRequestContext == null || servletRequestContext.getServletRequest() == null) { doDestroySession(context, session); } else { pushRequestReleasable(new Runnable() { // call it at the end of the request http://git-wip-us.apache.org/repos/asf/tomee/blob/51e9d77d/container/openejb-core/src/main/java/org/apache/openejb/service/ScanJarService.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/service/ScanJarService.java b/container/openejb-core/src/main/java/org/apache/openejb/service/ScanJarService.java index cc09e5b..55bc62c 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/service/ScanJarService.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/service/ScanJarService.java @@ -20,20 +20,23 @@ import org.apache.openejb.cdi.CompositeBeans; import org.apache.openejb.config.EjbModule; import org.apache.openejb.config.FinderFactory; import org.apache.openejb.config.ReadDescriptors; +import org.apache.openejb.config.WebModule; import org.apache.openejb.config.event.BeforeAppInfoBuilderEvent; import org.apache.openejb.core.ParentClassLoaderFinder; import org.apache.openejb.jee.Beans; import org.apache.openejb.observer.Observes; -import org.apache.openejb.util.URLs; import org.apache.xbean.finder.archive.FileArchive; import org.apache.xbean.finder.archive.JarArchive; import java.io.File; +import java.io.FileFilter; import java.io.FileInputStream; import java.io.InputStream; import java.net.URL; import java.net.URLClassLoader; -import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; import java.util.List; /** @@ -42,72 +45,136 @@ import java.util.List; * Definition can look like: * * 1. scanner = new://Service?class-name=org.apache.openejb.service.ScanJarService - * 2. scanner.url = cdi-lib/foo.jar + * 2. scanner.path = cdi-lib/foo.jar * + * if url is a directory containing multiple libs just use scanner.directory = true */ public class ScanJarService { - private URL url; - private final List<String> beans = new ArrayList<>(); - private Beans beansModel; + private File path; + private boolean directory; - public void addScanningResult(@Observes final BeforeAppInfoBuilderEvent event) { - for (final EjbModule ejbModule : event.getAppModule().getEjbModules()) { + private volatile CompositeBeans beans; + + public void addScanningResult(@Observes final BeforeAppInfoBuilderEvent event) throws Exception { + for (final EjbModule ejbModule : event.getAppModule().getEjbModules()) { // ear if (ejbModule.getModuleId().startsWith("ear-scoped-cdi-beans")) { - final Beans beans = ejbModule.getBeans(); - if (CompositeBeans.class.isInstance(beans)) { - final CompositeBeans cb = CompositeBeans.class.cast(beans); - cb.getManagedClasses().put(url, new ArrayList<>(this.beans)); - - if (beansModel != null) { - if (beansModel.getAlternativeClasses() != null) { - cb.getAlternativesByUrl().put(url, beansModel.getAlternativeClasses()); - } - if (beansModel.getAlternativeStereotypes() != null) { - cb.getAlternativeStereotypesByUrl().put(url, beansModel.getAlternativeStereotypes()); - } - if (beansModel.getInterceptors() != null) { - cb.getInterceptorsByUrl().put(url, beansModel.getInterceptors()); - } - if (beansModel.getDecorators() != null) { - cb.getDecoratorsByUrl().put(url, beansModel.getDecorators()); - } - } - } + doMerge(ejbModule); return; } } + // else a war + for (final WebModule webModule : event.getAppModule().getWebModules()) { + for (final EjbModule ejbModule : event.getAppModule().getEjbModules()) { + if (ejbModule.getModuleId().equals(webModule.getModuleId())) { + doMerge(ejbModule); + return; + } + } + } } - public void setUrl(final String url) throws Exception { - final File f = new File(url); - if (f.exists()) { - this.url = f.toURI().toURL(); - } else { - this.url = new URL(url); + private void doMerge(final EjbModule ejbModule) throws Exception { + final Beans beans = ejbModule.getBeans(); + if (CompositeBeans.class.isInstance(beans)) { + final CompositeBeans cb = CompositeBeans.class.cast(beans); + ensureInit(); + merge(cb); + } else if (beans != null) { + ensureInit(); + for (final URL key : this.beans.getManagedClasses().keySet()) { + beans.getManagedClasses().putAll(this.beans.getManagedClasses()); + addIfNotNull(beans.getInterceptors(), this.beans.getInterceptorsByUrl().get(key)); + addIfNotNull(beans.getAlternativeClasses(), this.beans.getAlternativesByUrl().get(key)); + addIfNotNull(beans.getAlternativeStereotypes(), this.beans.getAlternativeStereotypesByUrl().get(key)); + addIfNotNull(beans.getDecorators(), this.beans.getDecoratorsByUrl().get(key)); + } + } + } + + private void addIfNotNull(final List<String> out, final Collection<String> in) { + if (in != null) { + out.addAll(in); + } + } + + private void merge(final CompositeBeans cb) { + cb.getManagedClasses().putAll(this.beans.getManagedClasses()); + cb.getNotManagedClasses().putAll(this.beans.getNotManagedClasses()); + cb.getAlternativesByUrl().putAll(this.beans.getAlternativesByUrl()); + cb.getAlternativeStereotypesByUrl().putAll(this.beans.getAlternativeStereotypesByUrl()); + cb.getInterceptorsByUrl().putAll(this.beans.getInterceptorsByUrl()); + cb.getDecoratorsByUrl().putAll(this.beans.getDecoratorsByUrl()); + } + + private void ensureInit() throws Exception { + if (beans != null) { + return; } - final File file = URLs.toFile(this.url); - final ClassLoader loader = ParentClassLoaderFinder.Helper.get(); - beans.addAll( - new FinderFactory.OpenEJBAnnotationFinder( - file.isDirectory() ? new FileArchive(loader, file) : new JarArchive(loader, this.url)) - .getAnnotatedClassNames()); - - if (file.isDirectory()) { - final File beansXml = new File(file, "META-INF/beans.xml"); - if (beansXml.exists()) { - final FileInputStream inputStream = new FileInputStream(beansXml); - beansModel = ReadDescriptors.readBeans(inputStream); - inputStream.close(); + synchronized (this) { + if (beans != null) { + return; + } + + final ClassLoader loader = ParentClassLoaderFinder.Helper.get(); + final CompositeBeans mergedModel = new CompositeBeans(); + for (final File file : findFiles()) { + final URL url = file.toURI().toURL(); + if (file.isDirectory()) { + final FinderFactory.OpenEJBAnnotationFinder finder = new FinderFactory.OpenEJBAnnotationFinder(new FileArchive(loader, file)); + mergedModel.getManagedClasses().put(url, finder.getAnnotatedClassNames()); + + final File beansXml = new File(file, "META-INF/beans.xml"); + if (beansXml.exists()) { + final FileInputStream inputStream = new FileInputStream(beansXml); + final Beans beansModel = ReadDescriptors.readBeans(inputStream); + mergedModel.mergeClasses(url, beansModel); + inputStream.close(); + } + } else { + final FinderFactory.OpenEJBAnnotationFinder finder = new FinderFactory.OpenEJBAnnotationFinder(new JarArchive(loader, url)); + mergedModel.getManagedClasses().put(url, finder.getAnnotatedClassNames()); + + try (final URLClassLoader cl = new URLClassLoader(new URL[]{ url })) { + final InputStream is = cl.getResourceAsStream("META-INF/beans.xml"); + if (is != null) { + final Beans beansModel = ReadDescriptors.readBeans(is); + mergedModel.mergeClasses(url, beansModel); + is.close(); + } + } + } } + + beans = mergedModel; + } + } + + private Iterable<? extends File> findFiles() { + final Collection<File> files = new LinkedList<>(); + if (!directory) { + files.add(path); } else { - final URLClassLoader cl = new URLClassLoader(new URL[] { this.url }); - final InputStream is = cl.getResourceAsStream("META-INF/beans.xml"); - if (is != null) { - beansModel = ReadDescriptors.readBeans(is); - is.close(); + final File[] children = path.listFiles(new FileFilter() { + @Override + public boolean accept(final File pathname) { + final String name = pathname.getName(); + return name.endsWith(".jar") || name.endsWith(".zip") || pathname.isDirectory(); + } + }); + if (children != null) { + Collections.addAll(files, children); } - cl.close(); } + return files; + } + + public void setPath(final String path) throws Exception { + this.path = new File(path).getCanonicalFile(); + + } + + public void setDirectory(final boolean directory) { + this.directory = directory; } } http://git-wip-us.apache.org/repos/asf/tomee/blob/51e9d77d/tck/cdi-embedded/pom.xml ---------------------------------------------------------------------- diff --git a/tck/cdi-embedded/pom.xml b/tck/cdi-embedded/pom.xml index e2c9e08..8ee76d9 100644 --- a/tck/cdi-embedded/pom.xml +++ b/tck/cdi-embedded/pom.xml @@ -203,6 +203,7 @@ <openejb.cdi.producer.interception>false</openejb.cdi.producer.interception> <openejb.cdi.filter.classloader>false</openejb.cdi.filter.classloader> + <openejb.assembler>org.apache.openejb.tck.cdi.embedded.CleanUpAssembler</openejb.assembler> <openejb.jul.forceReload>true</openejb.jul.forceReload> <openejb.strict.interface.declaration>true</openejb.strict.interface.declaration> <openejb.http.mock-request>true</openejb.http.mock-request> http://git-wip-us.apache.org/repos/asf/tomee/blob/51e9d77d/tck/cdi-embedded/src/test/java/org/apache/openejb/tck/cdi/embedded/CleanUpAssembler.java ---------------------------------------------------------------------- diff --git a/tck/cdi-embedded/src/test/java/org/apache/openejb/tck/cdi/embedded/CleanUpAssembler.java b/tck/cdi-embedded/src/test/java/org/apache/openejb/tck/cdi/embedded/CleanUpAssembler.java new file mode 100644 index 0000000..1db29af --- /dev/null +++ b/tck/cdi-embedded/src/test/java/org/apache/openejb/tck/cdi/embedded/CleanUpAssembler.java @@ -0,0 +1,30 @@ +/* + * 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.tck.cdi.embedded; + +import org.apache.openejb.UndeployException; +import org.apache.openejb.assembler.classic.AppInfo; +import org.apache.openejb.assembler.classic.Assembler; +import org.jboss.cdi.tck.util.ActionSequence; + +public class CleanUpAssembler extends Assembler { + @Override + public void destroyApplication(final AppInfo appInfo) throws UndeployException { + super.destroyApplication(appInfo); + ActionSequence.reset(); + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/51e9d77d/tck/cdi-embedded/src/test/java/org/apache/openejb/tck/cdi/embedded/StandaloneTckCleaner.java ---------------------------------------------------------------------- diff --git a/tck/cdi-embedded/src/test/java/org/apache/openejb/tck/cdi/embedded/StandaloneTckCleaner.java b/tck/cdi-embedded/src/test/java/org/apache/openejb/tck/cdi/embedded/StandaloneTckCleaner.java deleted file mode 100644 index a9b42a8..0000000 --- a/tck/cdi-embedded/src/test/java/org/apache/openejb/tck/cdi/embedded/StandaloneTckCleaner.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.tck.cdi.embedded; - -import org.jboss.cdi.tck.util.ActionSequence; -import org.testng.IInvokedMethod; -import org.testng.IInvokedMethodListener; -import org.testng.ITestResult; - -public class StandaloneTckCleaner implements IInvokedMethodListener { - @Override - public void beforeInvocation(final IInvokedMethod iInvokedMethod, final ITestResult iTestResult) { - // no-op - } - - @Override - public void afterInvocation(final IInvokedMethod iInvokedMethod, final ITestResult iTestResult) { - ActionSequence.reset(); - } -} http://git-wip-us.apache.org/repos/asf/tomee/blob/51e9d77d/tck/cdi-embedded/src/test/resources/failing.xml ---------------------------------------------------------------------- diff --git a/tck/cdi-embedded/src/test/resources/failing.xml b/tck/cdi-embedded/src/test/resources/failing.xml index 4d56571..fd8ed45 100644 --- a/tck/cdi-embedded/src/test/resources/failing.xml +++ b/tck/cdi-embedded/src/test/resources/failing.xml @@ -35,7 +35,7 @@ org.jboss.cdi.tck.interceptors.tests.contract.aroundTimeout.bindings.AroundTimeoutOrderInterceptorTest org.jboss.cdi.tck.tests.extensions.lifecycle.processInjectionTarget.ContainerEventTest --> - <class name="org.jboss.cdi.tck.tests.context.session.listener.SessionContextHttpSessionListenerTest" /> + <class name="org.jboss.cdi.tck.tests.context.request.event.remote.RequestScopeEventRemoteTest" /> </classes> </test> </suite> http://git-wip-us.apache.org/repos/asf/tomee/blob/51e9d77d/tck/cdi-embedded/src/test/resources/passing.xml ---------------------------------------------------------------------- diff --git a/tck/cdi-embedded/src/test/resources/passing.xml b/tck/cdi-embedded/src/test/resources/passing.xml index 4f29ed7..89debb3 100644 --- a/tck/cdi-embedded/src/test/resources/passing.xml +++ b/tck/cdi-embedded/src/test/resources/passing.xml @@ -48,7 +48,6 @@ <listener class-name="org.testng.reporters.XMLReporter"/> <listener class-name="org.testng.reporters.EmailableReporter"/> <listener class-name="org.apache.openejb.tck.cdi.embedded.HTMLReporter"/> - <listener class-name="org.apache.openejb.tck.cdi.embedded.StandaloneTckCleaner"/> </listeners> <test name="JSR-346 TCK">
