diff --git a/container-api/src/main/java/org/jboss/forge/container/services/ServiceRegistry.java b/container-api/src/main/java/org/jboss/forge/container/services/ServiceRegistry.java index 7a087d833c..8fce472f8b 100644 --- a/container-api/src/main/java/org/jboss/forge/container/services/ServiceRegistry.java +++ b/container-api/src/main/java/org/jboss/forge/container/services/ServiceRegistry.java @@ -11,7 +11,7 @@ /** * Contains the collection of all installed and available {@link ExportedInstance} types. - * + * * @author Lincoln Baxter, III */ public interface ServiceRegistry diff --git a/container/src/main/java/org/jboss/forge/container/impl/ServiceRegistryImpl.java b/container/src/main/java/org/jboss/forge/container/impl/ServiceRegistryImpl.java index fcea84e94c..7c0dc5d7a3 100644 --- a/container/src/main/java/org/jboss/forge/container/impl/ServiceRegistryImpl.java +++ b/container/src/main/java/org/jboss/forge/container/impl/ServiceRegistryImpl.java @@ -40,48 +40,51 @@ public void addService(Class clazz) services.add(clazz); } - @SuppressWarnings("unchecked") @Override - public ExportedInstance getExportedInstance(Class clazz) + @SuppressWarnings("unchecked") + public ExportedInstance getExportedInstance(String clazz) { ensureAddonStarted(); + Class type; try { - final Class type; - if (clazz.getClassLoader() == addon.getClassLoader()) - { - type = clazz; - } - else - { - type = (Class) Class.forName(clazz.getName(), true, addon.getClassLoader()); - } - if (!manager.getBeans(type).isEmpty()) - { - return new ExportedInstanceImpl(addon.getClassLoader(), manager, type); - } + type = (Class) loadAddonClass(clazz); + return (ExportedInstance) getExportedInstance(type, type); } - catch (Exception e) + catch (ClassNotFoundException e) { - log.log(Level.FINE, "Error while fetching exported instances", e); + return null; } - return null; } @Override - @SuppressWarnings("unchecked") - public ExportedInstance getExportedInstance(String clazz) + public ExportedInstance getExportedInstance(Class clazz) + { + ensureAddonStarted(); + return getExportedInstance(clazz, clazz); + } + + /** + * @param requestedType interface + * @param actualType Implementation + * @return + */ + private ExportedInstance getExportedInstance(Class requestedType, Class actualType) { - Class type; try { - type = Class.forName(clazz, true, addon.getClassLoader()); - return (ExportedInstance) getExportedInstance(type); + final Class requestedLoadedType = loadAddonClass(requestedType); + final Class actualLoadedType = loadAddonClass(actualType); + if (!manager.getBeans(requestedLoadedType).isEmpty()) + { + return new ExportedInstanceImpl(addon.getClassLoader(), manager, requestedLoadedType, actualLoadedType); + } } - catch (ClassNotFoundException e) + catch (Exception e) { - return null; + log.log(Level.FINE, "Error while fetching exported instances", e); } + return null; } @Override @@ -95,7 +98,7 @@ public boolean hasService(String clazz) { try { - Class type = Class.forName(clazz, true, addon.getClassLoader()); + Class type = loadAddonClass(clazz); return hasService(type); } catch (ClassNotFoundException e) @@ -107,78 +110,110 @@ public boolean hasService(String clazz) @Override public boolean hasService(Class clazz) { + Class type; + try + { + type = loadAddonClass(clazz); + } + catch (ClassNotFoundException e) + { + return false; + } for (Class service : services) { - if (clazz.isAssignableFrom(service)) + if (type.isAssignableFrom(service)) + { return true; + } } return false; } @Override - public String toString() + @SuppressWarnings("unchecked") + public Set> getExportedInstances(String clazz) { - return services.toString(); + try + { + Class type = (Class) loadAddonClass(clazz); + return getExportedInstances(type); + } + catch (ClassNotFoundException e) + { + return Collections.emptySet(); + } } - @Override @SuppressWarnings("unchecked") - public Set> getExportedInstances(Class clazz) + @Override + public Set> getExportedInstances(Class requestedType) { + ensureAddonStarted(); Set> result = new HashSet>(); - final Class addonLoadedType; - if (clazz.getClassLoader() == addon.getClassLoader()) + Class requestedLoadedType; + try { - addonLoadedType = clazz; + requestedLoadedType = loadAddonClass(requestedType); } - else + catch (ClassNotFoundException e) { - try - { - addonLoadedType = (Class) Class.forName(clazz.getName(), true, addon.getClassLoader()); - } - catch (Exception e) - { - log.log(Level.FINE, "Error while fetching exported instances", e); - return result; - } + return result; } - for (Class type : services) { - - if (addonLoadedType.isAssignableFrom(type)) + if (requestedLoadedType.isAssignableFrom(type)) { - result.add((ExportedInstance) getExportedInstance(type)); + Class assignableClass = (Class) type; + result.add(new ExportedInstanceImpl(addon.getClassLoader(), manager, requestedLoadedType, + assignableClass)); } } return result; } - @Override - public Set> getExportedInstances(String clazz) + private void ensureAddonStarted() { try { - @SuppressWarnings("unchecked") - Class type = (Class) Class.forName(clazz, true, addon.getClassLoader()); - return getExportedInstances(type); + addon.getFuture().get(); } - catch (ClassNotFoundException e) + catch (Exception e) { - return Collections.emptySet(); + throw new ContainerException("Addon was not started.", e); } } - private void ensureAddonStarted() + /** + * Ensures that the returned class is loaded from the addon + * + * @param actualType + * @return + * @throws ClassNotFoundException + */ + @SuppressWarnings("unchecked") + private Class loadAddonClass(Class actualType) throws ClassNotFoundException { - try + final Class type; + if (actualType.getClassLoader() == addon.getClassLoader()) { - addon.getFuture().get(); + type = actualType; } - catch (Exception e) + else { - throw new ContainerException("Addon was not started.", e); + type = (Class) loadAddonClass(actualType.getName()); } + return type; + } + + private Class loadAddonClass(String className) throws ClassNotFoundException + { + return Class.forName(className, true, addon.getClassLoader()); } + + @Override + public String toString() + { + return services.toString(); + } + } diff --git a/container/src/main/java/org/jboss/forge/container/services/ExportedInstanceImpl.java b/container/src/main/java/org/jboss/forge/container/services/ExportedInstanceImpl.java index 3cd397ea1d..f5e4df4b3d 100644 --- a/container/src/main/java/org/jboss/forge/container/services/ExportedInstanceImpl.java +++ b/container/src/main/java/org/jboss/forge/container/services/ExportedInstanceImpl.java @@ -20,14 +20,18 @@ public class ExportedInstanceImpl implements ExportedInstance { private ClassLoader loader; private BeanManager manager; - private Class type; private CreationalContext context; - public ExportedInstanceImpl(ClassLoader loader, BeanManager manager, Class type) + private Class requestedType; + private Class actualType; + + public ExportedInstanceImpl(ClassLoader loader, BeanManager manager, Class requestedType, + Class actualType) { this.loader = loader; this.manager = manager; - this.type = type; + this.requestedType = requestedType; + this.actualType = actualType; } @Override @@ -39,10 +43,10 @@ public R get() @Override public Object call() throws Exception { - Bean bean = (Bean) manager.resolve(manager.getBeans(type)); + Bean bean = (Bean) manager.resolve(manager.getBeans(actualType)); context = manager.createCreationalContext(bean); - Object delegate = manager.getReference(bean, type, context); - return Enhancer.create((Class) type, new RemoteClassLoaderInterceptor(loader, delegate)); + Object delegate = manager.getReference(bean, actualType, context); + return Enhancer.create(requestedType, new RemoteClassLoaderInterceptor(loader, delegate)); } }; @@ -59,10 +63,10 @@ public Object get(final InjectionPoint injectionPoint) @Override public Object call() throws Exception { - Bean bean = (Bean) manager.resolve(manager.getBeans(type)); + Bean bean = (Bean) manager.resolve(manager.getBeans(actualType)); context = manager.createCreationalContext(bean); Object delegate = manager.getInjectableReference(injectionPoint, context); - return Enhancer.create((Class) type, new RemoteClassLoaderInterceptor(loader, delegate)); + return Enhancer.create(requestedType, new RemoteClassLoaderInterceptor(loader, delegate)); } }; @@ -78,7 +82,16 @@ public void release(R instance) @Override public String toString() { - return "RemoteInstanceImpl [type=" + type + ", classLoader=" + type.getClassLoader() + "]"; + StringBuilder builder = new StringBuilder(); + builder.append("ExportedInstanceImpl ["); + if (requestedType != null) + builder.append("requestedType=").append(requestedType).append(", "); + if (actualType != null) + builder.append("actualType=").append(actualType).append(", "); + if (loader != null) + builder.append("loader=").append(loader); + builder.append("]"); + return builder.toString(); } private class RemoteClassLoaderInterceptor implements MethodInterceptor