Cannot use warp-servlet with injected Wicket Applications

2 views
Skip to first unread message

Gili

unread,
Jul 23, 2008, 8:27:57 PM7/23/08
to warp-core
Hi,

I have an Application whose constructor contains a reference to
MyRequest which is @RequestScoped. When I launch my application I get
this exception:

com.google.inject.ProvisionException: Error while locating instance
bound to desktopbeautifier.web.RequestContext
for member at
desktopbeautifier.web.Application.<init>(Application.java:89)
at com.google.inject.InjectorImpl
$SingleParameterInjector.inject(InjectorImpl.java:646)
at
com.google.inject.InjectorImpl.getParameters(InjectorImpl.java:666)
at
com.google.inject.ConstructorInjector.construct(ConstructorInjector.java:
140)
at com.google.inject.InjectorImpl
$ImplicitBinding.get(InjectorImpl.java:1006)
at com.google.inject.BindingBuilderImpl
$FactoryProxy.get(BindingBuilderImpl.java:299)
at com.google.inject.InjectorImpl$9$1.call(InjectorImpl.java:
708)
at
com.google.inject.InjectorImpl.callInContext(InjectorImpl.java:747)
at com.google.inject.InjectorImpl$9.get(InjectorImpl.java:702)
at
com.google.inject.InjectorImpl.getInstance(InjectorImpl.java:728)
at
org.apache.wicket.guice.GuiceWebApplicationFactory.createApplication(GuiceWebApplicationFactory.java:
176)
at
org.apache.wicket.protocol.http.WicketFilter.init(WicketFilter.java:
543)
at
org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:
275)
at
org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:
397)
at
org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:
108)
at
org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:
3709)
at
org.apache.catalina.core.StandardContext.start(StandardContext.java:
4356)
at
org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:
791)
at
org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:
771)
at
org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
at
org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:
626)
at
org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:
553)
at
org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:488)
at
org.apache.catalina.startup.HostConfig.start(HostConfig.java:1147)
at
org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:
311)
at
org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:
117)
at
org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
at
org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at
org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at
org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at
org.apache.catalina.core.StandardService.start(StandardService.java:
516)
at
org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:
578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:
288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:
413)
Caused by: com.wideplay.warp.servlet.OutOfScopeException: Cannot
access scoped object. Either we are not currently inside an HTTP
Servlet request, or you may have forgotten to apply
com.wideplay.warp.servlet.WebFilter as a servlet filter for this
request.
at
com.wideplay.warp.servlet.ContextManager.getContext(ContextManager.java:
70)
at
com.wideplay.warp.servlet.ContextManager.getRequest(ContextManager.java:
60)
at com.wideplay.warp.servlet.Servlets$2$1.get(Servlets.java:
60)
at
com.google.inject.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:
41)
at com.google.inject.InjectorImpl
$SingleParameterInjector.inject(InjectorImpl.java:640)

Does this mean that warp-servlet doesn't work for injected
Applications?

Thank you,
Gili

Gili

unread,
Jul 23, 2008, 8:36:34 PM7/23/08
to warp-core
Here is my web.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<listener>
<listener-class>desktopbeautifier.servlet.ServletContextInjector</
listener-class>
</listener>
<filter>
<filter-name>WarpServletFilter</filter-name>
<filter-class>com.wideplay.warp.servlet.WebFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>WarpServletFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Official releases -->
<filter>
<filter-name>Webpage</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-
class>
<init-param>
<param-name>applicationFactoryClassName</param-name>
<param-value>org.apache.wicket.guice.GuiceWebApplicationFactory</
param-value>
</init-param>
<init-param>
<param-name>module</param-name>
<param-value>desktopbeautifier.web.GuiceModule</param-value>
</init-param>
<!--
<init-param>
<param-name>configuration</param-name>
<param-value>deployment</param-value>
</init-param>
-->
</filter>
<filter-mapping>
<filter-name>Webpage</filter-name>
<url-pattern>/main/*</url-pattern>
</filter-mapping>
<!---->
<filter>
<filter-name>RedirectMain</filter-name>
<filter-class>desktopbeautifier.web.filter.PermanentRedirect</
filter-class>
<init-param>
<param-name>source</param-name>
<param-value>/Main</param-value>
</init-param>
<init-param>
<param-name>target</param-name>
<param-value>/main</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>RedirectMain</filter-name>
<url-pattern>/Main/*</url-pattern>
</filter-mapping>
<!---->
<filter>
<filter-name>RedirectWallpapers</filter-name>
<filter-class>desktopbeautifier.web.filter.PermanentRedirect</
filter-class>
<init-param>
<param-name>source</param-name>
<param-value>/main/wallpapers</param-value>
</init-param>
<init-param>
<param-name>target</param-name>
<param-value>/main</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>RedirectWallpapers</filter-name>
<url-pattern>/main/wallpapers/*</url-pattern>
</filter-mapping>
<!---->
<filter>
<filter-name>RedirectDownload</filter-name>
<filter-class>desktopbeautifier.web.filter.PermanentRedirect</
filter-class>
<init-param>
<param-name>source</param-name>
<param-value>/download/DesktopBeautifier-Setup.exe$</param-
value>
</init-param>
<init-param>
<param-name>target</param-name>
<param-value>/main/resources/main/DesktopBeautifier-Setup.exe</
param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>RedirectDownload</filter-name>
<url-pattern>/download/DesktopBeautifier-Setup.exe</url-pattern>
</filter-mapping>
<!---->
<filter>
<filter-name>RedirectShared</filter-name>
<filter-class>desktopbeautifier.web.filter.PermanentRedirect</
filter-class>
<init-param>
<param-name>source</param-name>
<param-value>/main/resources/shared</param-value>
</init-param>
<init-param>
<param-name>target</param-name>
<param-value>/main/resources/main</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>RedirectShared</filter-name>
<url-pattern>/main/resources/shared/*</url-pattern>
</filter-mapping>
<!---->
<filter>
<filter-name>RedirectGallery</filter-name>
<filter-class>desktopbeautifier.web.filter.PermanentRedirect</
filter-class>
<init-param>
<param-name>source</param-name>
<param-value>/main/gallery</param-value>
</init-param>
<init-param>
<param-name>target</param-name>
<param-value>/main/gallery/small</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>RedirectGallery</filter-name>
<url-pattern>/main/gallery</url-pattern>
</filter-mapping>
<!---->
<servlet>
<servlet-name>Unpack200</servlet-name>
<servlet-class>com.sun.pack200.Unpack200</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Unpack200</servlet-name>
<url-pattern>/Unpack200</url-pattern>
</servlet-mapping>
<!---->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jspx</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>
</web-app>

Gili

unread,
Jul 23, 2008, 11:51:16 PM7/23/08
to warp-core
The documentation at http://www.wideplay.com/wicketwithwarp-servlet
needs to be updated. Recent versions of Wicket-Guice no longer require
the user to add any code to Application.init(), instead
GuiceWebApplicationFactory.createApplication() registers a
ComponentInstantiationListener on behalf of the user.

As a result, warp-servlet no longer gets a chance to register itself
by adding Wicket.integrate() in Application.init(). In theory the
following should work:

<filter>
<filter-name>Webpage</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-
class>
<init-param>
<param-name>applicationFactoryClassName</param-name>
<param-value>org.apache.wicket.guice.GuiceWebApplicationFactory</
param-value>
</init-param>
<init-param>
<param-name>injectorContextAttribute</param-name>
<param-value>com.google.inject.Injector</param-value>
</init-param>
</filter>

It should cause GuiceWebApplicationFactory to grab the Injector
created by warp-servlet, but for some reason it does not help (I get
the same exception). I am investigating further...

Gili

On Jul 23, 8:36 pm, Gili <gili.tzab...@gmail.com> wrote:
> Here is my web.xml file:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

Gili

unread,
Jul 24, 2008, 1:19:46 AM7/24/08
to warp-core
Okay I figured it out. Both WicketFilter and
GuiceWebApplicationFactory initialize the Application at init() time
whereas warp-servlet initializes the context at doFilter() time. When
the Application constructor tries making use of warp-servlet it is not
yet initialized and fails in the aforementioned manner.

I'm going to try updating warp-servlet's WebFilter to make this work.

Gili

On Jul 23, 11:51 pm, Gili <gili.tzab...@gmail.com> wrote:
> The documentation athttp://www.wideplay.com/wicketwithwarp-servlet
> > xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/we...">

Gili

unread,
Jul 24, 2008, 1:37:19 AM7/24/08
to warp-core
Nevermind... It turns out this is actually caused by user error. The
code is constructing the Wicket Application at initialization time,
before an HTTP request begins, yet the Application constructor depends
on a @RequestScoped variable which makes it impossible for the
variable to be initialized.

I feel so stupid having wasted so many hours trying to track this
problem down. I wish I knew how to make this problem more obvious to
ensure that no one else makes the same mistake... The message read
"OutOfScopeException: Cannot access scoped object. Either we are not
currently inside an HTTP Servlet request, or you may have forgotten to
apply com.wideplay.warp.servlet.WebFilter as a servlet filter for this
request." but for some reason it didn't click in my head that
constructing the Application was outside of an HTTP request :(

At the very least, I think we need to make the following changes to
the "warp-servlet + Wicket guide". As of Wicket 1.3.x users are
required to use:

<filter>
<filter-name>Webpage</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</
filter-
class>
<init-param>
<param-name>applicationFactoryClassName</param-name>
<param-
value>org.apache.wicket.guice.GuiceWebApplicationFactory</
param-value>
</init-param>
<init-param>
<param-name>injectorContextAttribute</param-name>
<param-value>com.google.inject.Injector</param-value>
</init-param>
</filter>


Please confirm that you read this last post by replying :)

Thank you,
Gili

Dhanji R. Prasanna

unread,
Jul 24, 2008, 5:41:49 AM7/24/08
to warp...@googlegroups.com
On Thu, Jul 24, 2008 at 3:37 PM, Gili <gili.t...@gmail.com> wrote:

Nevermind... It turns out this is actually caused by user error. The
code is constructing the Wicket Application at initialization time,
before an HTTP request begins, yet the Application constructor depends
on a @RequestScoped variable which makes it impossible for the
variable to be initialized.

I feel so stupid having wasted so many hours trying to track this
problem down. I wish I knew how to make this problem more obvious to
ensure that no one else makes the same mistake... The message read
"OutOfScopeException: Cannot access scoped object. Either we are not
currently inside an HTTP Servlet request, or you may have forgotten to
apply com.wideplay.warp.servlet.WebFilter as a servlet filter for this
request." but for some reason it didn't click in my head that
constructing the Application was outside of an HTTP request :(
 
=)

This is mentioned in the warp-servlet docs home page. And workarounds are shown in the (source code) examples. Perhaps I should make it more clear in the Wicket page too.

You needn't feel aggrieved for not spotting it, this happens reasonably often. So much so I am writing a whole section on it in my book.


At the very least, I think we need to make the following changes to
the "warp-servlet + Wicket guide". As of Wicket 1.3.x users are
required to use:

 <filter>
   <filter-name>Webpage</filter-name>
   <filter-class>org.apache.wicket.protocol.http.WicketFilter</
filter-
class>
   <init-param>
     <param-name>applicationFactoryClassName</param-name>
     <param-
value>org.apache.wicket.guice.GuiceWebApplicationFactory</
param-value>
   </init-param>
   <init-param>
     <param-name>injectorContextAttribute</param-name>
     <param-value>com.google.inject.Injector</param-value>
   </init-param>
 </filter>

Well, the point was you don't use the GuiceWebApplicationFactory, instead just use Integrate.with() as the instructions suggest. Perhaps I should make that explicit too.

This allows warp-servlet to act as the factory for Wicket. In any case I will take this up with the Wicket folk and get their opinion on the best approach.

Dhanji.

Gili

unread,
Jul 24, 2008, 5:53:51 AM7/24/08
to warp-core
On Jul 24, 5:41 am, "Dhanji R. Prasanna" <dha...@gmail.com> wrote:

> Well, the point was you don't use the GuiceWebApplicationFactory, instead
> just use Integrate.with() as the instructions suggest. Perhaps I should make
> that explicit too.
>
> This allows warp-servlet to act as the factory for Wicket. In any case I
> will take this up with the Wicket folk and get their opinion on the best
> approach.

The problem with the approach you propose is that it doesn't allow you
to use Guice to construct your Application. The approach I mentioned
will let you do that.

Gili
Reply all
Reply to author
Forward
0 new messages