Я пытаюсь загрузить spring dm в свой пакет OSGi. Я следовал руководству. Моя цель состоит в том, чтобы для определенного URL-адреса URL-адрес должен обрабатываться Spring вместо сервлета sling по умолчанию. Я частично преуспеваю в достижении того же самого.
Иногда это не работает. Мой сервлет globaldispatcher не инициализируется. Проблема возникает периодически. Иногда мой весенний сервлет инициализируется просто отлично. Но иногда я получаю эту ошибку:
[SpringOsgiExtenderThread-2] net.jasonday.examples.sling.spring.mvc.sling.SlingDispatcherServlet FrameworkServlet 'globaldispatcher': initialization started
[SpringOsgiExtenderThread-2] net.jasonday.examples.sling.spring.mvc.sling.SlingDispatcherServlet Context initialization failed
java.lang.IllegalArgumentException: bundle context should be set before refreshing the application context
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.normalRefresh(AbstractDelegatedExecutionApplicationContext.java:179)
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$NoDependenciesWaitRefreshExecutor.refresh(AbstractDelegatedExecutionApplicationContext.java:89)
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:175)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:467)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:483)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:358)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:325)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.sling.servlets.resolver.internal.SlingServletResolver.createServlet(SlingServletResolver.java:988)
at org.apache.sling.servlets.resolver.internal.SlingServletResolver.bindServlet(SlingServletResolver.java:936)
at sun.reflect.GeneratedMethodAccessor36.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
Версия Java: 1.7.0_45
Я использую следующие зависимости, как указано в учебнике: (Все это пакеты OSGi )
Spring AOP v3.0.6.RELEASE
Spring ASM v3.0.6.RELEASE
Spring Aspects v3.0.6.RELEASE
Spring Beans v3.0.6.RELEASE
Spring Context v3.0.6.RELEASE
Spring Context Support v3.0.6.RELEASE
Spring Core v3.0.6.RELEASE
Spring Expression v3.0.6.RELEASE
Spring Web v3.0.6.RELEASE
Spring Web Servlet v3.0.6.RELEASE
Spring OSGi IO v1.2.1
Spring OSGi Core v1.2.1
Spring OSGi Extender v1.2.1
Spring OSGi Annotation v1.2.1
Spring OSGi Web v1.2.1
AOP Alliance v1.0.0
CGLib 2.2.0
Commons Lang v2.6
Commons Codec v1.5
Commons Logging v1.1.1
ASM v3.2.0
JSR 330 (javax.inject) v1.0.0
JSR 250 (javax.annotation) v1.0.0
Ниже приведен код из моего файла spring-osgi.xml, который находится в папке META-INF/spring/.
<osgi:service ref="globalSlingDispatcherServlet">
<osgi:interfaces>
<value>javax.servlet.Servlet</value>
</osgi:interfaces>
<osgi:service-properties>
<entry key="sling.servlet.resourceTypes" value="examples/sling/spring/mvc/dispatcher/global" />
<entry key="sling.servlet.extensions">
<array>
<value>json</value>
<value>html</value>
</array>
</entry>
<entry key="sling.servlet.methods">
<array>
<value>GET</value>
<value>POST</value>
</array>
</entry>
<entry key="contextClass" value="org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext"/>
<entry key="sling.core.servletName" value="globaldispatcher" />
</osgi:service-properties>
Below is the code from META-INF\spring\spring.xml
<context:annotation-config />
<context:component-scan base-package="net.jasonday.examples.sling.spring.mvc.sling" />
<aop:aspectj-autoproxy />
<bean class="org.springframework.osgi.extensions.annotation.ServiceReferenceInjectionBeanPostProcessor" />
Ниже приведен код из WEB-INF/globaldispatcher.
<context:annotation-config />
<context:component-scan base-package="net.jasonday.examples.sling.spring.mvc">
<context:exclude-filter type="regex"
expression="net\.jasonday\.examples\.sling\.spring\.mvc\.sling\..*" />
</context:component-scan>
<aop:aspectj-autoproxy />
<bean class="org.springframework.osgi.extensions.annotation.ServiceReferenceInjectionBeanPostProcessor" />
SlingConfiguration.java:
@Configuration
public class SlingConfiguration {
@Bean
@DependsOn("slingContextLoader")
public SlingDispatcherServlet globalSlingDispatcherServlet() {
return new SlingDispatcherServlet();
}
}
SlingContextLoader.java:
@Component
public class SlingContextLoader extends ContextLoader {
private ServletContext servletContext;
private ApplicationContext applicationContext;
public ApplicationContext getApplicationContext() {
return applicationContext;
}
@Inject
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public ServletContext getServletContext() {
return servletContext;
}
@ServiceReference
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
@Override
protected Class<?> determineContextClass(
ServletContext currentServletContext) {
return OsgiBundleXmlWebApplicationContext.class;
}
@Override
protected ApplicationContext loadParentContext(
ServletContext currentServletContext) {
return applicationContext;
}
@PostConstruct
public void init() {
initWebApplicationContext(servletContext);
}
@PreDestroy
public void destroy() {
closeWebApplicationContext(servletContext);
}
}
Мой SlingDispatcherServlet.java
public class SlingDispatcherServlet extends DispatcherServlet implements Servlet {
@PreDestroy
@Override
public void destroy() {
super.destroy();
String attrName = getServletContextAttributeName();
getServletContext().removeAttribute(attrName);
}
}