Work in progress
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/b02ca6e4 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/b02ca6e4 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/b02ca6e4 Branch: refs/heads/tomee-1.7.x Commit: b02ca6e4f7040bdf822b81844dea896da33afd8c Parents: 19b8af0 Author: Jonathan Gallimore <j...@jrg.me.uk> Authored: Wed Jul 19 15:39:38 2017 +0100 Committer: Jonathan Gallimore <j...@jrg.me.uk> Committed: Tue Jul 25 12:58:29 2017 +0100 ---------------------------------------------------------------------- .../openejb/assembler/classic/Assembler.java | 87 ++++++++++++++++++-- .../openejb/assembler/classic/ResourceInfo.java | 2 + .../org/apache/openejb/testing/Classes.java | 2 +- .../ApplicationResourceLifecycleTest.java | 9 +- 4 files changed, 87 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/b02ca6e4/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 f58b360..e1e2b7b 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 @@ -1051,10 +1051,19 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A clazz = containerSystemContext.lookup(OPENEJB_RESOURCE_JNDI_PREFIX + resourceInfo.id).getClass(); } - final AnnotationFinder finder = new AnnotationFinder(new ClassesArchive(ancestors(clazz))); - final List<Method> postConstructs = finder.findAnnotatedMethods(PostConstruct.class); - final List<Method> preDestroys = finder.findAnnotatedMethods(PreDestroy.class); final boolean initialize = "true".equalsIgnoreCase(String.valueOf(resourceInfo.properties.remove("InitializeAfterDeployment"))); + final AnnotationFinder finder = Proxy.isProxyClass(clazz) ? + null : new AnnotationFinder(new ClassesArchive(ancestors(clazz))); + final List<Method> postConstructs = finder == null ? + Collections.<Method>emptyList() : finder.findAnnotatedMethods(PostConstruct.class); + final List<Method> preDestroys = finder == null ? + Collections.<Method>emptyList() : finder.findAnnotatedMethods(PreDestroy.class); + + resourceInfo.postConstructMethods = new ArrayList<String>(); + resourceInfo.preDestroyMethods = new ArrayList<String>(); + + addMethodsToResourceInfo(resourceInfo.postConstructMethods, PostConstruct.class, postConstructs); + addMethodsToResourceInfo(resourceInfo.preDestroyMethods, PreDestroy.class, preDestroys); CreationalContext<?> creationalContext = null; Object originalResource = null; @@ -1112,6 +1121,7 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A if (originalResource == null) { originalResource = containerSystemContext.lookup(name); } + this.bindResource(resourceInfo.id, new ResourceInstance(name, originalResource, preDestroys, creationalContext), true); } } @@ -1134,6 +1144,18 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A } } + private void addMethodsToResourceInfo(final List<String> list, final Class type, final List<Method> methodList) throws OpenEJBException { + for (final Method method : methodList) { + if (method.getParameterTypes().length > 0) { + throw new OpenEJBException(type.getSimpleName() + " method " + + method.getDeclaringClass().getName() + "." + + method.getName() + " should have zero arguments"); + } + + list.add(method.getName()); + } + } + private static boolean isTemplatizedResource(final ResourceInfo resourceInfo) { // ~ container resource even if not 100% right return resourceInfo.className == null || resourceInfo.className.isEmpty(); } @@ -1748,6 +1770,7 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A private void destroyResource(final String name, final String className, final Object object) { + if (ResourceAdapterReference.class.isInstance(object)) { final ResourceAdapterReference resourceAdapter = ResourceAdapterReference.class.cast(object); try { @@ -1844,8 +1867,60 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A logger.debug("Not processing resource on destroy: " + className); } + callPreDestroy(name, object); removeResourceInfo(name); } + + private void callPreDestroy(final String name, final Object object) { + if (object == null) { + return; + } + + if (ResourceInstance.class.isInstance(object)) { + ResourceInstance.class.cast(object).destroyResource(); + return; + } + + final Class<?> objectClass = object.getClass(); + + final ResourceInfo ri = findResourceInfo(name); + if (ri == null) { + return; + } + + final Set<String> destroyMethods = new HashSet<String>(); + if (ri.preDestroy != null) { + destroyMethods.add(ri.preDestroy); + } + + if (ri.preDestroyMethods != null && ri.preDestroyMethods.size() > 0) { + destroyMethods.addAll(ri.preDestroyMethods); + } + + for (final String destroyMethod : destroyMethods) { + try { + final Method p = objectClass.getDeclaredMethod(destroyMethod); + if (!p.isAccessible()) { + SetAccessible.on(p); + } + p.invoke(object); + } catch (Exception e) { + logger.error("Unable to call pre destroy method " + destroyMethod + " on " + + objectClass.getName() + ". Continuing with resource destruction.", e); + } + } + } + + private ResourceInfo findResourceInfo(String name) { + List<ResourceInfo> resourceInfos = config.facilities.resources; + for (final ResourceInfo resourceInfo : resourceInfos) { + if (resourceInfo.id.equals(name)) { + return resourceInfo; + } + } + + return null; + } public void removeResourceInfo(final String name) { try { @@ -2282,12 +2357,6 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A continue; } - if (DestroyableResource.class.isInstance(binding.getObject())) { - final DestroyableResource destroyableResource = DestroyableResource.class.cast(binding.getObject()); - destroyableResource.destroyResource(); - globalContext.unbind(name); - return; - } if (!LazyObjectReference.class.isInstance(binding.getObject())) { continue; http://git-wip-us.apache.org/repos/asf/tomee/blob/b02ca6e4/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ResourceInfo.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ResourceInfo.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ResourceInfo.java index c24ae24..05bf0da 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ResourceInfo.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ResourceInfo.java @@ -24,6 +24,8 @@ public class ResourceInfo extends ServiceInfo { public String jndiName = ""; public String postConstruct; public String preDestroy; + public List<String> postConstructMethods; + public List<String> preDestroyMethods; public String originAppName; // if define by an app public List<String> aliases = new ArrayList<String>(); } http://git-wip-us.apache.org/repos/asf/tomee/blob/b02ca6e4/container/openejb-core/src/main/java/org/apache/openejb/testing/Classes.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/testing/Classes.java b/container/openejb-core/src/main/java/org/apache/openejb/testing/Classes.java index b96cbc2..6e8db18 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/testing/Classes.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/testing/Classes.java @@ -22,7 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Target(ElementType.METHOD) +@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Classes { Class<?>[] value() default {}; http://git-wip-us.apache.org/repos/asf/tomee/blob/b02ca6e4/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ApplicationResourceLifecycleTest.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ApplicationResourceLifecycleTest.java b/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ApplicationResourceLifecycleTest.java index 48c0c6b..13574cf 100644 --- a/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ApplicationResourceLifecycleTest.java +++ b/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ApplicationResourceLifecycleTest.java @@ -27,15 +27,17 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; +import java.util.concurrent.Callable; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -@Classes @SimpleLog public class ApplicationResourceLifecycleTest { @Resource(name = "test") private MyResource resource; + @Classes({MyResource.class}) @Module public Resources resources() { return new Resources() {{ @@ -48,11 +50,12 @@ public class ApplicationResourceLifecycleTest { @Test public void lifecycle() throws Exception { - new ApplicationComposers(this).evaluate(this, new Runnable() { + new ApplicationComposers(this).evaluate(this, new Callable<Void>() { @Override - public void run() { + public Void call() throws Exception { assertTrue(resource.init); assertFalse(resource.destroy); + return null; } }); assertTrue(resource.init);