mirror of https://github.com/apache/jclouds.git
essential problem from Issue 803:lifecycle calls such as executorService.close() not called
This commit is contained in:
parent
0f71ae1596
commit
ef021720b1
|
@ -35,10 +35,13 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.concurrent.MoreExecutors;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
|
||||
import com.google.common.util.concurrent.ExecutionList;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.ProvisionException;
|
||||
import com.google.inject.Stage;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.spi.InjectionListener;
|
||||
import com.google.inject.spi.TypeEncounter;
|
||||
|
@ -49,6 +52,15 @@ import com.google.inject.spi.TypeListener;
|
|||
* {@link PostConstruct} after injection, and Associate {@link PreDestroy} with a global
|
||||
* {@link Closer} object.
|
||||
*
|
||||
* <h3>Important</h3> Make sure you create your injector with {@link Stage#PRODUCTION} and execute
|
||||
* the bound {@link ExecutionList} prior to using any other objects.
|
||||
*
|
||||
* <p/>
|
||||
* Ex.
|
||||
* <pre>
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class LifeCycleModule extends AbstractModule {
|
||||
|
@ -75,10 +87,13 @@ public class LifeCycleModule extends AbstractModule {
|
|||
Closer closer = new Closer();
|
||||
closer.addToClose(executorCloser);
|
||||
bind(Closer.class).toInstance(closer);
|
||||
bindPostInjectionInvoke(closer);
|
||||
|
||||
ExecutionList list = new ExecutionList();
|
||||
bindPostInjectionInvoke(closer, list);
|
||||
bind(ExecutionList.class).toInstance(list);
|
||||
}
|
||||
|
||||
protected void bindPostInjectionInvoke(final Closer closer) {
|
||||
protected void bindPostInjectionInvoke(final Closer closer, final ExecutionList list) {
|
||||
bindListener(any(), new TypeListener() {
|
||||
public <I> void hear(TypeLiteral<I> injectableType, TypeEncounter<I> encounter) {
|
||||
Set<Method> methods = new HashSet<Method>();
|
||||
|
@ -93,8 +108,8 @@ public class LifeCycleModule extends AbstractModule {
|
|||
}
|
||||
}
|
||||
|
||||
private <I> void associatePreDestroyWithCloser(final Closer closer,
|
||||
TypeEncounter<I> encounter, final Method method) {
|
||||
private <I> void associatePreDestroyWithCloser(final Closer closer, TypeEncounter<I> encounter,
|
||||
final Method method) {
|
||||
PreDestroy preDestroy = method.getAnnotation(PreDestroy.class);
|
||||
if (preDestroy != null) {
|
||||
encounter.register(new InjectionListener<I>() {
|
||||
|
@ -117,20 +132,23 @@ public class LifeCycleModule extends AbstractModule {
|
|||
}
|
||||
}
|
||||
|
||||
private <I> void invokePostConstructMethodAfterInjection(TypeEncounter<I> encounter,
|
||||
final Method method) {
|
||||
private <I> void invokePostConstructMethodAfterInjection(TypeEncounter<I> encounter, final Method method) {
|
||||
PostConstruct postConstruct = method.getAnnotation(PostConstruct.class);
|
||||
if (postConstruct != null) {
|
||||
encounter.register(new InjectionListener<I>() {
|
||||
public void afterInjection(I injectee) {
|
||||
try {
|
||||
method.invoke(injectee);
|
||||
} catch (InvocationTargetException ie) {
|
||||
Throwable e = ie.getTargetException();
|
||||
throw new ProvisionException(e.getMessage(), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ProvisionException(e.getMessage(), e);
|
||||
}
|
||||
public void afterInjection(final I injectee) {
|
||||
list.add(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
method.invoke(injectee);
|
||||
} catch (InvocationTargetException ie) {
|
||||
Throwable e = ie.getTargetException();
|
||||
throw new ProvisionException(e.getMessage(), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ProvisionException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}, MoreExecutors.sameThreadExecutor());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ import org.jclouds.concurrent.config.ExecutorServiceModule;
|
|||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.lifecycle.config.LifeCycleModule;
|
||||
import org.jclouds.location.Iso3166;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.location.config.ProvideIso3166CodesByLocationIdViaProperties;
|
||||
|
@ -80,12 +81,14 @@ import com.google.common.collect.ImmutableMultimap;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.util.concurrent.ExecutionList;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Stage;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
|
@ -194,8 +197,11 @@ public class RestContextBuilder<S, A> {
|
|||
ifHttpConfigureRestOtherwiseGuiceClientFactory(modules);
|
||||
addExecutorServiceIfNotPresent(modules);
|
||||
addCredentialStoreIfNotPresent(modules);
|
||||
modules.add(new LifeCycleModule());
|
||||
modules.add(new BindPropertiesAndPrincipalContext(properties));
|
||||
return Guice.createInjector(modules);
|
||||
Injector returnVal = Guice.createInjector(Stage.PRODUCTION, modules);
|
||||
returnVal.getInstance(ExecutionList.class).execute();
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
|
|
@ -27,6 +27,8 @@ import javax.inject.Named;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
|
||||
import com.google.common.util.concurrent.ExecutionList;
|
||||
import com.google.inject.name.Names;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -75,6 +77,9 @@ public class LifeCycleModuleTest {
|
|||
return 1;
|
||||
}
|
||||
}, new ExecutorServiceModule());
|
||||
// TODO: currently have to manually invoke the execution list, as otherwise it may occur
|
||||
// before everything is wired up
|
||||
i.getInstance(ExecutionList.class).execute();
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue