How do I inject a custom Executor into a play application? - java

I have assigned a dedicated thread pool for database operations via play-akka configuration file. For now I am injecting the services that require this thread pool with the actor system and accessing the execution context.
public class ServiceA{
final Executor executionContext;
#Inject
public ServiceA(ActorSystem system) {
this.executionContext = system.dispatchers().lookup("akka.actor.db-context");
}
But this makes it hard to test ServiceA. What I would like to do instead is just inject the Executor directly like this:
public class ServiceA{
final Executor executionContext;
#Inject
public ServiceA(Executor dbExecutionCtx) {
this.executionContext = dbExecutionCtx;
}
How do I achieve this? I have tried creating a guice module to inject the Executor but it errors out complaining that there is no started application and doesn't have access to ActorSystem when its doing it's binding the classes.

I use a pattern where I can get EC anywhere I want. I create an ActorSystem in a Singleton and get it injected into my services.
I have a design with ActorSystems, Dispatchers and a lot more for monitoring. Have a look at this and see if you can integrate it.
So if MyActorSystem is injected to your class you can access the EC from it. Have a look at MyDispatcher and the use of EC:
#Singleton
public class MyActorSystem implements IMyActorSystem{
ActorSystem system;
public MyActorSystem() {
system = ActorSystem.create();
}
public ActorRef create() {
final ActorRef actor = system.actorOf(
Props.create(MyWorker.class).withDispatcher("my-disp")
);
return actor;
}
public void shutdown(){
system.shutdown();
}
public ExecutionContextExecutor getDispatcher(){
return system.dispatcher();
}
}
public class MyDispatcher implements IMyDispatcher {
MyActorSystem system;
#Inject public MyDispatcher(MyActorSystem system) {
this.system = system;
}
public CompletableFuture<Object> dispatch(final Object story) {
List<CompletableFuture<Object>> futureList = new ArrayList<>();
final ActorRef actor = system.create();
final CompletableFuture<Object> completed = FutureConverter
.fromScalaFuture(Patterns.ask(actor, story, 50000)).executeOn(system.getDispatcher())
.thenApply(i -> (Object) i);
return completed;
}
public ExecutionContextExecutor getDispatcher(){
return system.getDispatcher();
}
}

Play as of 2.6 exposes DI bindings for its default dispatcher like this:
bind[ExecutionContextExecutor].toProvider[ExecutionContextProvider],
bind[ExecutionContext].to[ExecutionContextExecutor],
bind[Executor].to[ExecutionContextExecutor],
where ExecutionContextProvider is
#Singleton
class ExecutionContextProvider #Inject() (actorSystem: ActorSystem) extends Provider[ExecutionContextExecutor] {
def get = actorSystem.dispatcher
}
It looks like Play does not expose other named dispatchers in DI bindings, so you can do it yourself the same way but using #Named bindings. It is also possible to write a Play DI module which would dynamically expose all named akka dispatchers as corresponding named bindings.

Related

Right way of implementing a controllable scheduler

For my design I need a controllable schedular. Spring boot offers an #Scheduled annotation but that is more simplified and I do not have granular control.
So I wanted to implement my own scheduler manually.
This is the class I created:
#Slf4j
#Service
public class JobExecutor {
private static ScheduledExecutorService jobExecutor;
private static Environment env;
#Autowired
private JobExecutor(Environment env) {
JobExecutor.env = env;
}
public static ScheduledExecutorService INSTANCE() {
if (null == jobExecutor) {
synchronized (JobExecutor.class) {
if (null == jobExecutor) {
jobExecutor = Executors.newScheduledThreadPool(
Integer.parseInt(Objects.requireNonNull(env.getProperty("scheduler.jobs"))));
}
}
}
return jobExecutor;
}
}
With this approach I could simply call the static method to get a single instance.
Is this correct approach for a schedular? I need to start and stop and shutdown the jobs. I tried guava AbstractScheduledService but that does not seem to be working.
This is not the correct approach for creating a singleton, because double checked locking is broken. You're using Spring, so a) your JobExecutor will be a singleton anyway, and b) will only be created if it is needed. You might as well, therefore, create your executor instance in the constructor and get rid of those static methods.
Even better, you could create schedulers as named beans, and then inject them into classes where you want them:
#Configuration
public class ExecutorConfiguration {
#Bean
public ScheduledExecutorService jobExecutor(#Value("${scheduler.jobs}") jobs) {
return Executors.newScheduledThreadPool(jobs);
}
}
This says that whenever another component needs a ScheduledExecutorService, Spring should call this jobExecutor() method; Spring will automatically populate the jobs parameter from the scheduler.jobs property because of the #Value.
You can then inject your executor wherever you need it, for example with constructor injection (handily you're already using Lombok, so the amount of boilerplate is minimised):
#Service
#AllArgsConstructor
public class MyThingThatNeedsAScheduler {
private final ScheduledExecutorService jobExecutor;
// methods here...
}
You can also use setter or member injection, if you want.

Injecting a single Spring bean instance into a static variable of a utility class

I have this web application built with Spring and Vaadin, in which I wanted to do this, for the sake of convenience:
Create a utility class that wraps a Spring service, and allows the use of its static methods throughout the application, without having to worry about injecting this service everywhere, like so:
String configurationValue = ConfigurationUtil.getString("some.property.key");
If you work with Vaadin, you might see how convenient this is, because the whole presentation layer is written in Java and you can't always inject Spring services into your Vaadin components as these Vaadin components are not always Spring components themselves.
So this is my utility class:
public final class ConfigurationUtil {
// this is the spring service:
private static ConfigurationService configurationService;
public static void setConfigurationService(final ConfigurationService configurationService) {
ConfigurationUtil.configurationService = configurationService;
}
public static String getString(final String key) {
return configurationService.getString(key);
}
}
This is my service:
#Service("configurationService")
public class ConfigurationServiceImpl implements ConfigurationService, BeanFactoryAware {
private final FrameworkService frameworkService;
#Autowired
public ConfigurationServiceImpl(final FrameworkService frameworkService) throws IOException, ConfigurationException {
// this is where I set this service bean to the utility class
ConfigurationUtil.setConfigurationService(this);
this.frameworkService = frameworkService;
}
public String getString(String key) {
// code that retrieves a configuration value from our configuration files
}
}
My question here is: I'm a bit worried about this causing a bottleneck to access the configuration service, as multiple threads will be calling it, from multiple user sessions. Would this be a problem? Please explain why. Also, feel free to point out other problems with this solution.
I suggest to create a bean that implements ApplicationContextAware like this:
#Component
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
#Override
public void setApplicationContext(ApplicationContext ac) {
context = ac;
}
public static String getString(final String key) {
ConfigurationService configurationService = context.getBean(ConfigurationService.class);
return configurationService.getString(key);
}
public static <T> T bean(Class<T> beanType) {
return context.getBean(beanType);
}
}
You can create a method like in the example to give static access to Spring Beans or what you requested to get a String from your ConfigurationService.
Btw. I use this a lot in Vaadin applications because I don't want to make every component a Spring Bean.

Use Guice to create components to use with ThreadWeaver

The application I have been working on has been getting more and more complicated, and it's gotten to the point where I have been running into the same problems over and over again with concurrency. It no longer made any sense to solve the same problems and not have any regression tests.
That's when I found ThreadWeaver. It was really nice for some simple concurrency cases I cooked up, but I started to get frustrated when trying to do some more complicated cases with my production code. Specifically, when injecting components using Guice.
I've had a bit of a hard time understanding the implications of the way ThreadWeaver runs tests, and looked for any mention of Guice or DI in the wiki documents, but with no luck.
Is Guice compatible with ThreadWeaver?
Here is my test
#Test
public void concurrency_test() {
AnnotatedTestRunner runner = new AnnotatedTestRunner();
runner.runTests(OPYLWeaverImpl.class, OPYLSurrogateTranscodingService.class);
}
Here is my test implementation
public class OPYLWeaverImpl extends WeaverFixtureBase {
#Inject private TaskExecutor taskExecutor;
#Inject private Serializer serializer;
#Inject private CountingObjectFileMarshaller liveFileMarshaller;
#Inject private GraphModel graphModel;
#Inject private CountingModelUpdaterService updaterService;
#Inject private BabelCompiler babelCompiler;
#Inject private EventBus eventBus;
OPYLSurrogateTranscodingService service;
private Path testPath;
#ThreadedBefore
public void before() {
service = new OPYLSurrogateTranscodingService(eventBus, taskExecutor, serializer, liveFileMarshaller,
() -> new OPYLSurrogateTranscodingService.Importer(graphModel, babelCompiler, updaterService, eventBus),
() -> new OPYLSurrogateTranscodingService.Validator(eventBus, babelCompiler),
() -> new OPYLSurrogateTranscodingService.Exporter(graphModel, updaterService));
}
#ThreadedMain
public void mainThread() {
testPath = FilePathOf.OASIS.resolve("Samples/fake-powershell-unit-test.opyl");
service.applyToExistingGraphModel(testPath);
}
#ThreadedSecondary
public void secondaryThread() {
}
#ThreadedAfter
public void after() {
}
And the WeaverFixtureBase
public class WeaverFixtureBase {
#Inject protected CountingEventBus eventBus;
#Before public final void setupComponents() {
Injector injector = Guice.createInjector(new WeaverTestingEnvironmentModule(CommonSerializationBootstrapper.class));
injector.getMembersInjector((Class) this.getClass()).injectMembers(this);
}
private class WeaverTestingEnvironmentModule extends AbstractModule {
private final Class<? extends SerializationBootstrapper> serializationBootstrapper;
public WeaverTestingEnvironmentModule(Class<? extends SerializationBootstrapper> serializationConfiguration) {
serializationBootstrapper = serializationConfiguration;
}
#Override protected void configure() {
bind(TaskExecutor.class).to(FakeSerialTaskExecutor.class);
bind(SerializationBootstrapper.class).to(serializationBootstrapper);
bind(ModelUpdaterService.class).toInstance(new CountingModelUpdaterService());
bindFactory(StaticSerializationConfiguration.Factory.class);
CountingEventBus localEventBus = new CountingEventBus();
bind(Key.get(EventBus.class, Bindings.GlobalEventBus.class)).toInstance(localEventBus);
bind(Key.get(EventBus.class, Bindings.LocalEventBus.class)).toInstance(localEventBus);
bind(CountingEventBus.class).toInstance(localEventBus);
bind(EventBus.class).toInstance(localEventBus);
}
#Provides
#Singleton
public GraphModel getGraphModel(EventBus eventBus, Serializer serializer) {
return MockitoUtilities.createMockAsInterceptorTo(new GraphModel(eventBus, serializer));
}
}
But when the classloader loads OPYLWeaverImpl, none of the Guice stuff goes off and I get a big pile of nulls.
I feel like this is one of those "missing-something-really-simple" kind of scenarios. Sorry if it is!
The above comment is right. Thread-weaver is fully agnostic of JUnit. Thread weaver is its own runner that executes a test case respecting its own annotations. You must not use any JUnit-specific annotation within a Thread Weaver test.
Other than that, Thread Weaver does not need any compatibility for a specific framework. It manipulates Java byte code and loads that manipulated code using aeperate class loaders.
Finally, a Thread Weaver test without any secondary test does not make any sense. Thread weaver works by interleaving seperate execution paths. Without a second thread, Thread Weaver only steps through a single thread without adding any value.

How to inject dependency in a Quartz job using Dagger 2

I am using Dagger 2 as my DI framework and I am providing a singleton class instance with it.
I also use Quartz Scheduler to schedule jobs. Is there any way to inject the singleton class into the Quartz job?
Dagger 2 module:
#Module
public class MyModule {
#Provides
#Singleton
Messager provideMessager() {
return new CustomMessager();
}
}
Dagger 2 component:
#Component(modules = MyModule.class)
#Singleton
public interface MyComponent {
Messager messager();
}
Quartz Job:
public class MyJob implements Job {
// #Inject
Messager messager;
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
messager.sendMessage("Hello.");
}
}
EDIT
I have created a MyJobScheduler class that calls the Quartz Job:
public class MyJobScheduler {
public void scheduleJob() {
JobDetail myJob = JobBuilder.newJob(MyJob.class)
.withIdentity("myJobId", "Group1")
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("myTriggerId", "Group1")
.startNow()
.build();
Scheduler scheduler = new org.quartz.impl.StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(myJob, trigger);
}
}
EDIT 2
So I managed to configure it to work, but I don't know if this is the correct approach.
First I created a DependencyResolver class, which I use as a singleton:
public class DependencyResolver {
private static DependencyResolver _instance = null;
private static MyComponent _myComponent;
public static MyComponent getMyComponent() {
return _myComponent;
}
protected DependencyResolver() {
// Exists only to defeat instantiation.
}
public static void initialize() {
_myComponent = DaggerMyComponent.builder().build();
}
}
Then I called the initialize method in the main method:
DependencyResolver.initialize();
MyComponent myComponent = DependencyResolver.getMyComponent();
And I used the DependencyResolver in MyJob class to get the Messager singleton instance.
public class MyJob implements Job {
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
MyComponent myComponent = DependencyResolver.getMyComponent();
Messager messager = myComponent.messager();
messager.sendMessage("Hello.");
}
}
Is this the correct way to solve this issue? Any input will be greatly appreciated.
Your EDIT 2 DependencyResolver approach kind of defeats the whole reason to use Dagger to inject the dependencies, because your job gets the dependency from a singleton provider. :-) It completely bypasses the benefit of Dagger, so you might as well just have a singleton on the source dependency itself, like: Messager messager = CustomMessager.getInstance() or something like that.
One reason to use Dependency Injection, is to assist with unit testing, and in this case you're losing the ability to mock your Messager implementation in a unit test.
The proper way to use dependency injection with Quartz jobs is mentioned in the API doc for JobFactory: "This interface may be of use to those wishing to have their application produce Job instances via some special mechanism, such as to give the opertunity for dependency injection."
The trick is to create your own job factory that extends SimpleJobFactory and then you have an opportunity to initialize/inject the job's dependencies, something like this:
public class MyJobFactory extends SimpleJobFactory {
private final MyComponent component;
#Inject
public MyJobFactory(MyComponent component) {
this.component = component;
}
#Override
public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
final Job job = super.newJob(bundle, scheduler);
if (job instanceof MyJob) {
component.inject((MyJob) job);
}
return job;
}
}
And then you tell the scheduler to use your job factory:
scheduler.setJobFactory(myJobFactory);
See the full code here on GitHub

Builder Pattern Using Spring Injected Resources

I have a Builder that uses several resources that are injected via Spring. It looks similar to this:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class SandBoxBuilder {
private final SandUtil sandUtil;
private Sand sand;
private Box box;
#Autowired
public SandBoxBuilder(SandUtil sandUtil) {
this.sandUtil = sandUtil;
}
public SandBoxBuilder setSand(Sand sand) {
this.sand = sand;
return this;
}
public SandBoxBuilder setBox(Box box) {
this.box = box;
return this;
}
public SandBox build() {
SandBox sandBox = new SandBox(sand);
sandUtil.changeBox(sandBox, box);
return sandBox;
}
}
The problem I have with this is that it is not thread safe. I know that this builder should not be a singleton, but I am not sure how to use the spring injected resources (SandUtil) without wiring the builder up and injecting it where I use it.
How can I implement a thread safe builder that utilizes singletons injected by spring?
Solution
Because of some architectural constraints I could not inject the utilities into my calling classes. I ended up implementing a factory builder bean that returns new instances of a builder that has references to the spring resources.
Solution Implementation
#Component
public class SandBoxBuilderFactory {
private final SandUtil sandUtil;
#Autowired
public SandBoxBuilderFactory(SandUtil sandUtil) {
this.sandUtil = sandUtil;
}
public Builder newBuilder(){
return new Builder(sandUtil);
}
public static class Builder {
private final SandUtil sandUtil;
private Sand sand;
private Box box;
private Builder(SandUtil sandUtil) {
this.sandUtil = sandUtil;
}
public Builder setSand(Sand sand) {
this.sand = sand;
return this;
}
public Builder setBox(Box box) {
this.box = box;
return this;
}
public SandBox build() {
SandBox sandBox = new SandBox(sand);
sandUtil.changeBox(sandBox, box);
return sandBox;
}
}
}
Usage
newBuilder().setBox(box).setSand(sand).build();
You are using your SandBoxBuilder as a bean because of #Component. Wherever you need it, you must have access to the ApplicationContext. I would propose, instead of injecting the SandBoxBuilder bean, inject the SandUtil bean and use it to create SandBoxBuilder instances
#Service
public class MyService {
private final SandUtil sandUtil;
#Autowired
public MyService (SandUtil sandUtil) {
this.sandUtil = sandUtil;
}
public void someMethod() {
SandBoxBuilder builder = new SandBoxBuilder(sandUtil);
... // use it
}
}
Does SandUtil need to be a bean? It might fit as a static utility class.
I do not know much about the Spring IOC lately. I use the Tapestry IOC alot which should provide similar inner working.
First of all a singleton should be thread-safe per definition. So if you create the builder every time you use it, the builder does not need to be thread-safe. The SandUtil must be in itself threadsafe.
It's like a contract: If you are a singleton service you are injected in multiple threads. Therefore a singleton service has to be threadsafe (synchronized methods, shared lock, synchronized objects and so on). If your service is PerThread meaning the same service is only used within a single thread, it has not to be thread safe.
So ensure SandUtil is threadsafe and you are fine if Sandbox is PerThread or PerOccurence (new instance is created every time it is injected).
If you want to make the builder threadsafe since you can not be sure a single instance of it is only used within a thread - and you do not care much about performance - you can just add synchronized keyword to every non-private method of the builder class. This is the poor-mans concurrency control otherwise check out some tutorials about concurrency control like the original Java lesson
I'm guessing the non-thread-safe part of this has to do with the sandUtil field?
You can use external locking on the changeBox method to ensure synchronized access to it.
Otherwise, perhaps the 'prototype' bean scope would help you out?
http://docs.spring.io/spring/docs/3.0.x/reference/beans.html#beans-factory-scopes
http://docs.spring.io/spring/docs/3.0.x/reference/beans.html#beans-factory-scopes-prototype

Categories