I swear that I had this working on a small-scale web app last
week...But this week as I try to OSGi-ify a larger web app, I am
getting the following...
[Timer-1] ERROR
org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationCon text
- Refresh error
java.lang.NullPointerException
at
org.springframework.osgi.util.internal.MapBasedDictionary.put(MapBasedDicti onary.java:
142)
at
org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationCon text.customizeApplicationContextServiceProperties(OsgiBundleXmlWebApplicati onContext.java:
176)
at
org.springframework.osgi.context.support.AbstractOsgiBundleApplicationConte xt.publishContextAsOsgiServiceIfNecessary(AbstractOsgiBundleApplicationCont ext.java:
283)
at
org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicat ionContext.finishRefresh(AbstractDelegatedExecutionApplicationContext.java:
307)
at
org.springframework.context.support.AbstractApplicationContext.refresh(Abst ractApplicationContext.java:
384)
at
org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicat ionContext.normalRefresh(AbstractDelegatedExecutionApplicationContext.java:
143)
at
org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicat ionContext
$NoDependenciesWaitRefreshExecutor.refresh(AbstractDelegatedExecutionApplic ationContext.java:
70)
at
org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicat ionContext.refresh(AbstractDelegatedExecutionApplicationContext.java:
131)
at
org.springframework.web.context.ContextLoader.createWebApplicationContext(C ontextLoader.java:
255)
at
org.springframework.web.context.ContextLoader.initWebApplicationContext(Con textLoader.java:
199)
at
org.springframework.web.context.ContextLoaderListener.contextInitialized(Co ntextLoaderListener.java:
45)
at
org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java :
3843)
at
org.apache.catalina.core.StandardContext.start(StandardContext.java:
4350)
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.springframework.osgi.web.deployer.tomcat.TomcatWarDeployer.startCatalin aContext(TomcatWarDeployer.java:
144)
at
org.springframework.osgi.web.deployer.tomcat.TomcatWarDeployer.startDeploym ent(TomcatWarDeployer.java:
133)
at
org.springframework.osgi.web.deployer.support.AbstractWarDeployer.deploy(Ab stractWarDeployer.java:
93)
at
org.springframework.osgi.web.extender.internal.activator.WarLoaderListener
$DeploymentManager$DeployTask.run(WarLoaderListener.java:141)
at
org.springframework.scheduling.timer.DelegatingTimerTask.run(DelegatingTime rTask.java:
66)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
Digging around in the Spring-DM source I find that the problem is when
OsgiBundleXmlWebApplicationContext tried to add the web app's
namespace to MapBasedDictionary--the namespace is null and so
MapBasedDictionary throws a NullPointerException.
My web.xml file has the following bit of XML in it:
I do not have a DispatcherServlet (because I'm using a different web
framework on this project), but even if I add a dummy
DispatcherServlet, I get the same error.
I'm quite befuddled at the moment as to what I need to do to get this
to work. Any one with any clues?
Seeing as how everyone's silent on this issue (probably living it up
at JavaOne), I'll continue the discussion on my own. Pipe in if you
have anything to offer. :-)
On one of my small-scale example apps, I got this to work without the
aforementioned exceptions. I did this by loading the context entirely
from DispatcherServlet (that is, I added DispatcherServlet to web.xml
and a corresponding Spring config). What led me to this "solution" is
that I had discovered (by digging around in the Spring source code)
that DispatcherServlet calls setNamespace() on the context, but
ContextLoaderListener does not. Is this expected behavior?
Once I added ContextLoaderListener back to my XML file, I started
getting the exceptions again. Here's what my non-working web.xml file
looks like:
And yes, there is an applicationContext.xml file under WEB-INF with a
single stupid-simple bean declared in it. Note that this is not
significantly different than what is described in Section 8.7 of the
reference documentation.
So, what can I do to make this work and still be able to use
ContextLoaderListener? Is this a bug? I'll be happy to report in in
JIRA, but want to make sure that I'm not doing something wrong first.
Clarifying one point I made in my last post: The setNamespace() method
appears to only be called from three places:
- FrameworkServlet (and therefore from DispatcherServlet)
- FrameworkPortlet
- ContextLoaderPlugin (for Struts apps)
This would be no problem if my web layer were developed in Spring MVC
and I chose to pack all of the configuration for that layer in a
single XML file. But the web layer of at least one of my projects is
Wicket, thus there's no need for DispatcherServlet and I must load the
context with ContextLoaderListener. Unfortunately, as I've already
pointed out, that does not work, yielding the aforementioned
exception.
This appears to be a bug. Either ContextLoaderListener needs to be
changed to call setNamespace() or Spring-DM needs to be changed to be
more forgiving of the fact that there is no namespace set when all you
have is ContextLoaderListener.
On May 6, 9:03 am, Craig Walls <hab...@gmail.com> wrote:
> Seeing as how everyone's silent on this issue (probably living it up
> at JavaOne), I'll continue the discussion on my own. Pipe in if you
> have anything to offer. :-)
> On one of my small-scale example apps, I got this to work without the
> aforementioned exceptions. I did this by loading the context entirely
> from DispatcherServlet (that is, I added DispatcherServlet to web.xml
> and a corresponding Spring config). What led me to this "solution" is
> that I had discovered (by digging around in the Spring source code)
> that DispatcherServlet calls setNamespace() on the context, but
> ContextLoaderListener does not. Is this expected behavior?
> Once I added ContextLoaderListener back to my XML file, I started
> getting the exceptions again. Here's what my non-working web.xml file
> looks like:
> And yes, there is an applicationContext.xml file under WEB-INF with a
> single stupid-simple bean declared in it. Note that this is not
> significantly different than what is described in Section 8.7 of the
> reference documentation.
> So, what can I do to make this work and still be able to use
> ContextLoaderListener? Is this a bug? I'll be happy to report in in
> JIRA, but want to make sure that I'm not doing something wrong first.
On Tue, May 6, 2008 at 7:21 AM, Craig Walls <hab...@gmail.com> wrote:
> Clarifying one point I made in my last post: The setNamespace() method > appears to only be called from three places: > - FrameworkServlet (and therefore from DispatcherServlet) > - FrameworkPortlet > - ContextLoaderPlugin (for Struts apps)
> This would be no problem if my web layer were developed in Spring MVC > and I chose to pack all of the configuration for that layer in a > single XML file. But the web layer of at least one of my projects is > Wicket, thus there's no need for DispatcherServlet and I must load the > context with ContextLoaderListener. Unfortunately, as I've already > pointed out, that does not work, yielding the aforementioned > exception.
> This appears to be a bug. Either ContextLoaderListener needs to be > changed to call setNamespace() or Spring-DM needs to be changed to be > more forgiving of the fact that there is no namespace set when all you > have is ContextLoaderListener.
> On May 6, 9:03 am, Craig Walls <hab...@gmail.com> wrote: > > Seeing as how everyone's silent on this issue (probably living it up > > at JavaOne), I'll continue the discussion on my own. Pipe in if you > > have anything to offer. :-)
> > On one of my small-scale example apps, I got this to work without the > > aforementioned exceptions. I did this by loading the context entirely > > from DispatcherServlet (that is, I added DispatcherServlet to web.xml > > and a corresponding Spring config). What led me to this "solution" is > > that I had discovered (by digging around in the Spring source code) > > that DispatcherServlet calls setNamespace() on the context, but > > ContextLoaderListener does not. Is this expected behavior?
> > Once I added ContextLoaderListener back to my XML file, I started > > getting the exceptions again. Here's what my non-working web.xml file > > looks like:
> > And yes, there is an applicationContext.xml file under WEB-INF with a > > single stupid-simple bean declared in it. Note that this is not > > significantly different than what is described in Section 8.7 of the > > reference documentation.
> > So, what can I do to make this work and still be able to use > > ContextLoaderListener? Is this a bug? I'll be happy to report in in > > JIRA, but want to make sure that I'm not doing something wrong first.
> Just a thought - but is there a way to set the namespace as a <context-param>?
> Matt
> On Tue, May 6, 2008 at 7:21 AM, Craig Walls <hab...@gmail.com> wrote:
> > Clarifying one point I made in my last post: The setNamespace() method
> > appears to only be called from three places:
> > - FrameworkServlet (and therefore from DispatcherServlet)
> > - FrameworkPortlet
> > - ContextLoaderPlugin (for Struts apps)
> > This would be no problem if my web layer were developed in Spring MVC
> > and I chose to pack all of the configuration for that layer in a
> > single XML file. But the web layer of at least one of my projects is
> > Wicket, thus there's no need for DispatcherServlet and I must load the
> > context with ContextLoaderListener. Unfortunately, as I've already
> > pointed out, that does not work, yielding the aforementioned
> > exception.
> > This appears to be a bug. Either ContextLoaderListener needs to be
> > changed to call setNamespace() or Spring-DM needs to be changed to be
> > more forgiving of the fact that there is no namespace set when all you
> > have is ContextLoaderListener.
> > On May 6, 9:03 am, Craig Walls <hab...@gmail.com> wrote:
> > > Seeing as how everyone's silent on this issue (probably living it up
> > > at JavaOne), I'll continue the discussion on my own. Pipe in if you
> > > have anything to offer. :-)
> > > On one of my small-scale example apps, I got this to work without the
> > > aforementioned exceptions. I did this by loading the context entirely
> > > from DispatcherServlet (that is, I added DispatcherServlet to web.xml
> > > and a corresponding Spring config). What led me to this "solution" is
> > > that I had discovered (by digging around in the Spring source code)
> > > that DispatcherServlet calls setNamespace() on the context, but
> > > ContextLoaderListener does not. Is this expected behavior?
> > > Once I added ContextLoaderListener back to my XML file, I started
> > > getting the exceptions again. Here's what my non-working web.xml file
> > > looks like:
> > > And yes, there is an applicationContext.xml file under WEB-INF with a
> > > single stupid-simple bean declared in it. Note that this is not
> > > significantly different than what is described in Section 8.7 of the
> > > reference documentation.
> > > So, what can I do to make this work and still be able to use
> > > ContextLoaderListener? Is this a bug? I'll be happy to report in in
> > > JIRA, but want to make sure that I'm not doing something wrong first.
And registering it as a bean in the Spring context. The application
context gets loaded and the beans are instantiated (and thus
ContextNamespaceSetter sets the namespace for me). This seems to serve
as a good workaround, but is very non-ideal. It will suffice until the
real solution comes along.
I am also having the same issues that you described above, but with a
very basic spring MVC web bundle. I was following your workaround
suggestion.
- I created a class as you specified but I get compilation errors from
Eclipse as follows:
"Access restriction: The type ApplicationContext is not accessible due
to restriction on required library
org.springframework.bundle.spring_2.5.4.v200804181548.jar
ContextNamespaceSetter.java line 4"
-Also, how did you register it as a bean? I defined it in my
applicationContext.xml file as follows:
> And registering it as a bean in the Spring context. The application
> context gets loaded and the beans are instantiated (and thus
> ContextNamespaceSetter sets the namespace for me). This seems to serve
> as a good workaround, but is very non-ideal. It will suffice until the
> real solution comes along.
First problem: You must have the Spring bundle deployed in the OSGi
container *and* you need to have the proper Import-Package entries in
MANIFEST.MF for your Spring MVC application.
Second problem: I configured ContextNamespaceSetter like this:
Note that I'm not sure if "habuma" is a good value for the namespace
or not, but it works.
Also, you'll get the error I get even with a Spring MVC application if
you use ContextLoaderListener. I have another application that has a
rather skinny web layer and only uses DispatcherServlet and I get no
errors. But if as soon as I start using ContextLoaderListener the
errors start flying.
> First problem: You must have the Spring bundle deployed in the OSGi > container *and* you need to have the proper Import-Package entries in > MANIFEST.MF for your Spring MVC application.
> Second problem: I configured ContextNamespaceSetter like this:
> Note that I'm not sure if "habuma" is a good value for the namespace > or not, but it works.
> Also, you'll get the error I get even with a Spring MVC application if > you use ContextLoaderListener. I have another application that has a > rather skinny web layer and only uses DispatcherServlet and I get no > errors. But if as soon as I start using ContextLoaderListener the > errors start flying.