Guice + Struts2 Integration

129 views
Skip to first unread message

Zarar Siddiqi

unread,
Mar 14, 2007, 12:11:37 AM3/14/07
to google-guice
I'm looking to use Guice as an IOC tool instead of Spring for my next
application. I've read the docs on Struts2 integration and have added
all the jars (guice.jar and guice-struts2-plugin.jar) to my
application. For some reason, the mappings defined in my custom
module class are not being recognized by Struts. Here's my setup:


struts.xml

<struts>
<constant name="struts.objectFactory" value="guice" />
<constant name="guice.module" value="com.arsenalist.MyModule"/>

<package name="defaultPackage" extends="struts-default">
<action name="viewLogin" class="com.arsenalist.LoginAction">
<result>/WEB-INF/jsp/login.jsp</result>
</action>
</package>
</struts>


MyModule.java

public class MyModule extends AbstractModule {
protected void configure() {
log.debug("inside configure"); // never gets printed
bind(Service.class)
.to(ServiceImpl.class)
.in(Scopes.SINGLETON);
}
}

LoginAction.java

public class LoginAction extend ActionSupport {
private Service service;

@Inject
public void setService(Service service) {
this.service = service;
}
public String execute() {
return SUCCESS;
}
}

However, when I run this I get the following error:

javax.servlet.ServletException: Unable to instantiate Action,
com.arsenalist.LoginAction, defined for 'viewLogin' in namespace
'/'com.opensymphony.xwork2.inject.ContainerImpl
$MissingDependencyException: No mapping found for dependency
[type=com.arsenalist.Service, name='default'] in public void
com.arsenalist.LoginAction.setService(com.arsenalist.Service).

org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:
518)

org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:
421)

com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:
118

com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:
52)

org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:
99)

Now, it can't find a mapping for com.arsenalist.Service even though
one is defined in MyModule and MyModule is referenced using the
guice.module constant inside the struts.xml file. I never see the
debug statement in the logs so the MyModule.configure() never gets
called. Any ideas how to have Guice/Struts2 recognize the mappings in
MyModule? I'm following the setup instructions here:

http://docs.google.com/Doc?id=dd2fhx4z_5df5hw8

Thanks.
Zarar

Bob Lee

unread,
Mar 14, 2007, 12:19:18 AM3/14/07
to google...@googlegroups.com
That exception is coming from Struts' internally packaged version of Guice (an old version, FWIW). I suspect you imported @Inject from Struts instead of com.google.inject.Inject.

Bob

[type=com.arsenalist.Service , name='default'] in public void

Zarar Siddiqi

unread,
Mar 14, 2007, 12:30:53 AM3/14/07
to google-guice
Thanks for the reply. Yes, you're right. But I've tried
com.google.inject.Inject too and with that I get the following
exception which spells out the problem:

INFO: Creating injector...
com.google.inject.CreationException: Guice configuration errors:

1) Error at com.arsenalist.LoginAction.setService(LoginAction.java:
14):
Binding to com.arsenalist.Service not found. No bindings to that type
were found.

1 error[s]
at com.google.inject.BinderImpl.createInjector(BinderImpl.java:
277)
at com.google.inject.Guice.createInjector(Guice.java:79)
at com.google.inject.Guice.createInjector(Guice.java:53)
at com.google.inject.Guice.createInjector(Guice.java:43)
at
com.google.inject.struts2.GuiceObjectFactory.buildBean(GuiceObjectFactory.java:
101)
at
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:
152)
at
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:
141)
at
com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:
111)
at
com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:
270)
at
com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:
360)
at com.opensymphony.xwork2.DefaultActionInvocation.access
$000(DefaultActionInvocation.java:38)
at com.opensymphony.xwork2.DefaultActionInvocation
$1.doProfiling(DefaultActionInvocation.java:78)
at
com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:
455)
at
com.opensymphony.xwork2.DefaultActionInvocation.<init>(DefaultActionInvocation.java:
70)
at
com.opensymphony.xwork2.DefaultActionInvocation.<init>(DefaultActionInvocation.java:
66)
at
com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:
189)
at
org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:
41)
at
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:
497)
at
org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:
421)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
202)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
173)

> > [type=com.arsenalist.Service, name='default'] in public void

Bob Lee

unread,
Mar 14, 2007, 12:44:35 AM3/14/07
to google...@googlegroups.com
Hmmm... there could be a bug in the Struts 2 plugin. We're actually still on WebWork. I'll check it out and upload a new version of the plugin if this turns out to be the case.

Zarar Siddiqi

unread,
Mar 14, 2007, 12:57:59 AM3/14/07
to google-guice
Just to let you know if I don't specify a custom module class and
instead use annotations all the way, everything works. So for example,
the following setup works fine:

@ImplementedBy(ServiceImpl.class)
public interface Service {...}

@Singleton
public class ServiceImpl {...}

public class LoginAction extend ActionSupport {

...


@Inject
public void setService(Service service) {
this.service = service;
}

...
}

Zarar

> > com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:

> > > > org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java
> > :
> > > > 518)
>
> > > > org.apache.struts2.dispatcher.FilterDispatcher.doFilter(
> > > > FilterDispatcher.java:
> > > > 421)
>
> > > > com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(

Zarar Siddiqi

unread,
Mar 14, 2007, 11:05:31 AM3/14/07
to google-guice
Bob, I've created an issue and submitted a patch to fix this problem:

http://code.google.com/p/google-guice/issues/detail?id=63

Thanks,
Zarar


On Mar 14, 12:19 am, "Bob Lee" <crazy...@crazybob.org> wrote:

> > [type=com.arsenalist.Service, name='default'] in public void
> > com.arsenalist.LoginAction.setService(com.arsenalist.Service).
>
> > org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:
> > 518)
>


> > org.apache.struts2.dispatcher.FilterDispatcher.doFilter(
> > FilterDispatcher.java:
> > 421)
>
> > com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(
> > PageFilter.java:
> > 118
>
> > com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(
> > PageFilter.java:
> > 52)
>
> > org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(
> > ActionContextCleanUp.java:

Bob Lee

unread,
Mar 14, 2007, 12:01:56 PM3/14/07
to google...@googlegroups.com
Wow! Thanks. We'll get this in ASAP. We can upload a guice-struts jar on its own.

Bob

> > org.apache.struts2.dispatcher.Dispatcher.serviceAction (Dispatcher.java:
> > 518)
>
> > org.apache.struts2.dispatcher.FilterDispatcher.doFilter(
> > FilterDispatcher.java:
> > 421)
>
> > com.opensymphony.module.sitemesh.filter.PageFilter.parsePage (

Kevin Bourrillion

unread,
Mar 14, 2007, 12:33:51 PM3/14/07
to google...@googlegroups.com
I can't tell you how much we appreciate this approach to bug reporting. :-) :-)

K


On 3/14/07, Zarar Siddiqi < zar...@gmail.com> wrote:
> > org.apache.struts2.dispatcher.Dispatcher.serviceAction (Dispatcher.java:
> > 518)
>
> > org.apache.struts2.dispatcher.FilterDispatcher.doFilter(
> > FilterDispatcher.java:
> > 421)
>
> > com.opensymphony.module.sitemesh.filter.PageFilter.parsePage (
Reply all
Reply to author
Forward
0 new messages