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/7baf2605 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/7baf2605 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/7baf2605 Branch: refs/heads/master Commit: 7baf2605453814ccc9226a31b9a27550fee218cb Parents: c376184 Author: Jonathan Gallimore <j...@jrg.me.uk> Authored: Wed Jul 19 15:39:38 2017 +0100 Committer: Jonathan Gallimore <j...@jrg.me.uk> Committed: Wed Jul 19 15:39:38 2017 +0100 ---------------------------------------------------------------------- .../openejb/assembler/classic/Assembler.java | 83 ++++++++++++++++++-- .../openejb/assembler/classic/ResourceInfo.java | 2 + 2 files changed, 77 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/7baf2605/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 d0c0958..853e05c 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 @@ -1232,6 +1232,12 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A final List<Method> preDestroys = finder == null ? Collections.<Method>emptyList() : finder.findAnnotatedMethods(PreDestroy.class); + resourceInfo.postConstructMethods = new ArrayList<>(); + resourceInfo.preDestroyMethods = new ArrayList<>(); + + addMethodsToResourceInfo(resourceInfo.postConstructMethods, PostConstruct.class, postConstructs); + addMethodsToResourceInfo(resourceInfo.preDestroyMethods, PreDestroy.class, preDestroys); + CreationalContext<?> creationalContext = null; Object originalResource = null; if (!postConstructs.isEmpty() || initialize) { @@ -1288,6 +1294,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); } } @@ -1310,6 +1317,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(); } @@ -1991,9 +2010,61 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A doResourceDestruction(name, className, object); } + 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<>(); + 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; + } + private void doResourceDestruction(final String name, final String className, final Object jndiObject) { final ResourceBeforeDestroyed event = new ResourceBeforeDestroyed(jndiObject, name); SystemInstance.get().fireEvent(event); @@ -2056,7 +2127,7 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A } } - public void removeResourceInfo(final String name) { + public ResourceInfo removeResourceInfo(final String name) { try { //Ensure ResourceInfo for this resource is removed final OpenEjbConfiguration configuration = SystemInstance.get().getComponent(OpenEjbConfiguration.class); @@ -2070,12 +2141,14 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A final ResourceInfo info = iterator.next(); if (name.equals(info.id)) { iterator.remove(); - break; + return info; } } } catch (final Exception e) { logger.debug("Failed to purge resource on destroy: " + e.getMessage()); } + + return null; } private static Object unwrapReference(final Object object) { @@ -2484,12 +2557,6 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A if (!binding.getName().equals(objName)) { 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/7baf2605/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 5a2ace9..52791c9 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<>(); public List<String> dependsOn = new ArrayList<>();