Connecting gwt-dispatch with guice and mvp4g - gwt

I have some questions regarding gwt-dispatch and guice. I'm using Guice 2.0, gwt-dispatch 1.1.0 snapshot, mvp4g 1.1.0 and GIN 1.0
First of all, I have defined simple action, result and handler:
ListContactsAction.java
public class ListContactsAction implements Action<ListContactsResult>{
public ListContactsAction() {
}
}
ListContactsResult.java
public class ListContactsResult implements Result {
private List<Contact> contactList;
public ListContactsResult() {
}
public ListContactsResult(List<Contact> contactList) {
this.contactList = contactList;
}
public List<Contact> getContactList() {
return contactList;
}
}
ListContactsHandler.java
public class ListContactsHandler implements ActionHandler<ListContactsAction, ListContactsResult>{
#Inject
private SqlSessionFactory factory;
public Class<ListContactsAction> getActionType() {
return ListContactsAction.class;
}
public ListContactsResult execute(ListContactsAction a, ExecutionContext ec) throws DispatchException {
// some code using SqlSessionFactory and returning ListContactResult
// with list of contacts
}
public void rollback(ListContactsAction a, ListContactsResult r, ExecutionContext ec) throws DispatchException {
/* get action - no rollback needed */
}
}
In previous version of my app, which was using rpc service instead of command pattern, I had a method which was providing SqlSessionFactory for injections, something like this:
#Provides
public SqlSessionFactory getSqlSessionFactory(){
// some code here
}
I read on gwt-dispatch getting started that I have to provide binding between my action and it's handler, which should look something like that:
public class ContactModule extends ActionHandlerModule{
#Override
protected void configureHandlers() {
bindHandler(ListContactsAction.class, ListContactsHandler.class);
}
}
But I have problem wiring it all with Guice, because this example from gwt-dispatch site:
public class DispatchServletModule extends ServletModule {
#Override
public void configureServlets() {
serve( "/path/to/dispatch" ).with( DispatchServiceServlet.class );
}
}
doesn't work, since there is no DispatchServiceServlet in the package.
My questions are:
How should I write DispatchServletModule and how to make it going (with what I should serve path)
what should I put in the web.xml file of my app to be able to correctly execute actions from my presenter, which has GIN injected DispatcherAsync implementation
Where should I put my SqlSessionFactory providing method (in which module) to be able to inject SqlSessionFactory where I need it
How I instantiate the injector so then I can use it in other action handlers properly
I think that is all and I made myself clear. If something isn't clear enough, I'll try to be more specific.

Have you created a GuiceServletConfig class? This is where you setup your Dispatch servlet module as well as your action handler module with Guice.
plubic class GuiceServletConfig extends GuiceServletContextListener {
#Override
protected Injector getInjector() {
return Guice.createInjector(new HandlerModule(), new DispatchServletModule());
}
}
The HandlerModule is your ActionHandler module class, so from your code you would put your ContactModule class.
For your SqlSessionFactory, you could setup the binding for it in your ContactModule, with my code I only have a single ServerModule that sets up all my service and action handler bindings. This is mainly for the sake of simplicity.

GWT-Platform framework uses a gwt-dispatch fork to handle rpc requests. There's a lot of code, which you probably had to wtite yourself, if you think of seriously using dispatcher and Guice. I highly recommend it.

Firstly, I sympathise. Putting this all together isn't documented in any one spot. I'll answer each of your questions in turn. Add comments to my answer if any of it is unclear.
QU: How should I write DispatchServletModule and how to make it going (with what I should serve path)?
There's a GuiceStandardDispatchServlet class in the net.customware.gwt.dispatch.server.guice package; use that. I'm not 100 percent sure why, but the path I use includes the name of my GWT module, followed by '/dispatch'. You might have to experiment with that.
public class MyServletModule extends ServletModule {
#Override protected void configureServlets() {
serve("/com.my.module.name/dispatch")
.with(GuiceStandardDispatchServlet.class);
}
}
QU: what should I put in the web.xml file of my app to be able to correctly execute actions from my presenter, which has GIN injected DispatcherAsync implementation?
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.myapp.whatever.MyContextListener</listener-class>
</listener>
...
</web-app>
... and then you'll need a custom context listener that creates a Guice injector as follows. Notice that I've included your ContactModule, which binds action handlers.
public class MyContextListener extends GuiceServletContextListener {
#Override protected Injector getInjector() {
return Guice.createInjector(new MyServletModule(),
new ContactModule(), new SQLStuffModule());
}
}
QU: Where should I put my SqlSessionFactory providing method (in which module) to be able to inject SqlSessionFactory where I need it?
Notice that I included a new SQLStuffModule in the previous code snippet; that would be a good place to put your SqlSessionFactory binding. There's no harm having multiple modules, and I find that it keeps the various concerns nicely separated.
QU: How I instantiate the injector so then I can use it in other action handlers properly?
For the server-side, see the MyContextListener code snippet above.
On the client side, you'll need a custom injector interface something like this:
#GinModules(StandardDispatchModule.class, MyClientModule.class)
public interface MyGinjector extends Ginjector {
MyWidgetMainPanel getMainPanel();
}
...and you can bind your MVP stuff in a custom Gin module as follows. I'm sorry that I'm not familiar with mvp4g, but I assume that you'll need to wire the views and presenters together in the module class.
public class MyClientModule extends AbstractGinModule {
#Override protected void configure() {
bind(...).to(...);
...
}
}

Related

How to configure a Listener to override the behaviour of the class LoggingReporter in Citrus?

I'm looking for a way to remove stacktraces of fails assertions when using the framework Citrus.
This is done in testNg like this:
public class NoStackTraceListener implements ITestListener {
...
#Override
public void onTestFailure(ITestResult iTestResult) {
Throwable th = iTestResult.getThrowable();
if (Objects.nonNull(th)) {
System.out.println(th.getMessage());
iTestResult.setThrowable(null);
}
}
...
}
#Listeners({ NoStackTraceListener.class })
class A {...}
But I can't find any example of usgin the class 'TestListener' or others in order to override the supplied implementation of 'LoggingReporter'
Please do anyone has already overrided a Listener using framework citrus and could give the snippet to do so ?
Thanks
You need to add the custom reporter as bean to the Spring application context:
#Bean
public NoStackTraceReporter noStackTraceReporter() {
return new NoStackTraceReporter();
}
You can also overwrite the default logging reporter by choosing the bean name loggingReporter
#Bean
public NoStackTraceReporter loggingReporter() {
return new NoStackTraceReporter();
}
The NoStackTraceReporter implementation is then able to overwrite the specific event handler for failed tests:
public class NoStackTraceReporter extends LoggingReporter {
...
#Override
public void onTestFailure(TestCase test, Throwable cause) {
// do something customized
}
...
}
Also you may overwrite the generateTestResults() method in the reporter interface in order to customize logging results.
You can also follow the sample http://www.citrusframework.org/samples/reporting/ that demonstrates how to add customized reporters in Citrus.

Dagger2 Using an entire Dependency Graph

I have set up dagger2 dependencies in my app as I understand it and through the many examples. What I have not found is the proper way to use all of the dependencies once they are injected.
Each of the singletons in the module depends on the output of the singleton before it. How is the entire dependency graph used without calling each singleton in turn to get the required inputs?
Given the following:
AppComponent
#Singleton
#Component(modules = {
DownloaderModule.class
})
public interface AppComponent {
void inject(MyGameActivity activity);
}
DownloaderModule
#Module
public class DownloaderModule {
public static final String NETWORK_CACHE = "game_cache";
private static final int GLOBAL_TIMEOUT = 30; // seconds
public DownloaderModule(#NonNull String endpoint) {
this(HttpUrl.parse(endpoint));
}
#Provides #NonNull #Singleton
public HttpUrl getEndpoint() {
return this.endpoint;
}
#Provides #NonNull #Singleton #Named(NETWORK_CACHE)
public File getCacheDirectory(#NonNull Context context) {
return context.getDir(NETWORK_CACHE, Context.MODE_PRIVATE);
}
#Provides #NonNull #Singleton
public Cache getNetworkCache(#NonNull #Named(NETWORK_CACHE) File cacheDir) {
int cacheSize = 20 * 1024 * 1024; // 20 MiB
return new Cache(cacheDir, cacheSize);
}
#Provides #NonNull #Singleton
public OkHttpClient getHttpClient(#NonNull Cache cache) {
return new OkHttpClient.Builder()
.cache(cache)
.connectTimeout(GLOBAL_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(GLOBAL_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(GLOBAL_TIMEOUT, TimeUnit.SECONDS)
.build();
}
MyGameApp
public class MyGameApp extends Application {
private AppComponent component;
private static Context context;
public static MyGameApp get(#NonNull Context context) {
return (MyGameApp) context.getApplicationContext();
}
#Override
public void onCreate() {
super.onCreate();
component = buildComponent();
MyGameApp.context = getApplicationContext();
}
public AppComponent component() {
return component;
}
protected AppComponent buildComponent() {
return DaggerAppComponent.builder()
.downloaderModule(new DownloaderModule("https://bogus.com/"))
.build();
}
}
I'll try to shed some light into this, but there are several ways you can read this. I prefer a bottom up approach - Basically start on what your objects require and work my way up. In this case, I would start at MyGameActivity. Unfortunately, you didn't paste the code for this, so I'll have to be a bit creative, but that's ok for the purpose of the exercise.
So in your app you're probably getting the AppComponent and calling inject for your MyGameActivity. So I guess this activity has some injectable fields. I'm not sure if you're using there directly OkHttpClient but let's say you do. Something like:
public class MyGameActivity extends SomeActivity {
#Inject
OkHttpClient okHttpClient;
// ...
}
The way I like to think about this is as follows. Dagger knows you need an OkHttpClient given by the AppComponent. So it will look into how this can be provided - Can it build the object itself because you annotated the constructor with #Inject? Does it require more dependencies?.
In this case it will look into the modules of the component where this client is being provided. It will reach getHttpClient and realise it needs a Cache object. It will again look for how this object can be provided - Constructor injection, another provider method?.
It's again provided in the module, so it will reach getNetworkCache and once more realise it needs yet another dependency.
This behaviour will carry on, until it reaches objects that require no other dependencies, such as your HttpUrl in getEndpoint.
After all this is done, your OkHttpClient can be created.
I think it's easy to understand from this why you can't have cycles in your dependency graph - You cannot create an object A if it depends on B and B depends on A. So imagine that for some weird reason you'd reach the method getEndpoint which would depend on the OkHttpClient from that module. This wouldn't work. You'd be going in circles an never reach an end.
So if I understand your question: How is the entire dependency graph used without calling each singleton in turn to get the required inputs?
It's not. It has to call all the methods to be able to get the singletons. At least the first time they're provided within the same component/scope. After that, as long as you keep the same instance of your component, the scoped dependencies will always return the same instance. Dagger will make sure of this. If you'd for some reason destroy the component or recreate it, then the dependencies wouldn't be the same instances. More info here. In fact this is true for all scopes. Not just #Singletons.
However, as far as I can tell you're doing it right. When your application is created you create the component and cache it. After that, every time you use the method component() you return always the same component and the scoped dependencies are always the same.

Possible to detect when application starts successfully in Wildfly?

Is there a way to detect when a war file is successfully loaded by Wildfly and cause some code to execute?
You have a few options.
If you're leveraging CDI, you can add an observer method for #Observes #Initialized(ApplicationScoped.class) Object o
If you're leveraging EJBs, you can have a #javax.ejb.Singleton #javax.ejb.Startup with a #PostConstruct method that does initialization. Here are two example implementations.
// using a CDI object
#ApplicationScoped
public class SomeStartupBean {
public void initOnStartup(#Observes #Initialized(ApplicationScoped.class) Object obj) {
// do your start up logic here
}
}
or
// using an EJB
#Singleton
#Startup
public class SomeStartupSingleton {
#PostConstruct
public void initOnStartup() {
// do your start up logic here
}
}
You could use an #Startup EJB. That would execute when the application has successfully been deployed.

Setting data to view in GWT MVP

I have a GWT application where MVP pattern is followed.
We have multiple views to show data on UI.
We set the data to view via Activity. Something like this
public class SomeActivityImpl extends AbstractActivity implements SomeView.Presenter {
public SomeActivityImpl{
//some initialization goes here.
}
public void start(AcceptsOneWidget containerWidget, EventBus eventBus) {
//presenter is set here
loadDetails();
}
private void loadDetails(){
SomeRequestFactory.context().findSomeEntity().fire(new Receiver<SomeProxy>() {
#Override
public void onSuccess(SomeProxy proxyObject) {
someView.setName("name");
someview.setSurname("surname");
someview.setMothersName("mothers name");
}
)
}
Now my question is how can I make sure that all the setters of View are set and nothing is missed?
Is there any solution which is GWT specific or can someone suggest a design pattern?
You should use the editor framework. It has a Request Factory driver to help you use it with request Factory. Here's a good tutorial
If you don't like that tutorial, consider looking at GWT in action

Instance variable in Stripes

I'm trying to find a way to create an instance variable within the Stripes application context.
Something that i would do in the init() method of a Servlet while using hand-coded servlets.
The problem is that since an instance of the ActionBean is created each time the application is accessed, the variable in the actionBean is created multiple time.
I have tried to get some reasonable place withing Stripes trying to call the ServletContext via ActionBeanContext.getServletContext(), but from there there is no way to access the init() method and write some code in it.
Do you have any suggestions?
The ActionBeanContext is also Stripes application context. This context can be customized and can contain whatever you want. Some example code:
package my.app;
public class CustomActionBeanContext extends ActionBeanContext {
public CustomActionBeanContext() {
super();
}
public MyObject getMyObject() {
return (MyObject) getServletContext().getAttribute(“myObject”);
}
// Alternative solution without ServletContextListner
private static MyObject2 myObject2;
static {
myObject2 = new MyObject2();
}
public MyObject2 getMyObject2() {
return myObject2;
}
}
To let the Stripes context factory know you want to use a custom ActionBeanContext you need to add an init-param to the Stripes filter in the web.xml:
<init-param>
<param-name>ActionBeanContext.Class</param-name>
<param-value>my.app.CustomActionBeanContext</param-value>
</init-param>
You can initialize your object at server start by adding a SerlvetContextListener:
Public class MyServletContextListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("myObject", new MyObject());
}
Example ActionBean:
public class MyAction implements ActionBean {
private CustomActionBeanContext context;
#Override
public CustomActionBeanContext getContext() {
return context;
}
#Override
public void setContext(ActionBeanContext context) {
this.context = (CustomActionBeanContext) context;
}
#DefaultHandler
public Resolution view() {
MyObject myObject = getContext().getMyObject();
// doing something usefull with it..
}
}
An alternative solution, in my opinion a superiour solution, is to use a dependency injection framework for injecting the (singleton) objects into your actionbeans. See Stripes configuration example here: Injecting Stripes ActionBeans with Guice DI
Not a Stripes-specific way, but using the standard Servlet API you'd implement ServletContextListener and do the job in contextInitialized() method. If you register it as <listener> in web.xml (or when you're already on Java EE 6, annotate using #WebListener), then it'll run during webapp's startup.
#Override
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("somename", new SomeObject());
}
This way it's available in EL by ${somename} and in all action beans by ServletContext#getAttribute().
#JBoy, You have to specify your implementation of ServletContextListner in the web.xml like below
<listner>
<listner-class>
www.test.com.MyListner
</listner-class>
</listner>
Thanks KDeveloper for his advice. I was also searching for the solution. I found the information from his blog
There is one more method I have found out. For that you have to subclass the "RuntimeConfiguration" class
public class MyConfiguration extends RuntimeConfiguration {
#Override
public void init() {
getServletContext.setAttribute("myObject",new MyObject);
super.init();
}
}
After that in the web.xml specify the above configuration.
<init-param>
<param-name>Configuration.Class</param-name>
<param-value>www.test.com.MyConfiguration</param-value>
</init-param>
You also have to subclass the ActionBeanContext as KDeveloper said; to get the object in ActionBeans
This is my finding. I found out it is working. But I don't know whether it has any side effects. If it has any; please comment..