I am trying to integrate restlet in an application using Eclipse Virgo as the application server. As Virgo is based on OSGi, I had to use the org.restlet.osgi
libraries and the newest version (restlet 2.2.3) that doesn't rely on Java 1.7 because the latest Virgo release complains about bundles depending on Java 1.7.
I try to get restlet to use the Eclipse Virgo web server for delivering the REST APIs, but it seems like whatever I tried doesn't work. Of course, I can start the restlet own web server on a separate port than the Eclipse Virgo one, but I had no success using its web server. Is it at all possible?
Update
There is also Spring involved into the story, so I think this will make things even more interesting. The Spring related configuration is below:
<context-param>
<param-name>contextClass</param-name>
<param-value>org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springdispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springdispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
I am now getting this exception:
[2015-03-10 18:35:55.783] ERROR start-signalling-1 org.springframework.web.context.ContextLoader Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'restletComponent' defined in ServletContext resource [/WEB-INF/spring/app-config.xml]: Cannot resolve reference to bean 'router' while setting bean property 'defaultTarget'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'router' defined in ServletContext resource [/WEB-INF/spring/app-config.xml]: Cannot create inner bean 'org.restlet.ext.spring.SpringFinder#5700078' of type [org.restlet.ext.spring.SpringFinder] while setting bean property 'attachments' with key [TypedStringValue: value [/data/dashboard/geppettoprojects], target type [null]]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.restlet.ext.spring.SpringFinder#5700078' defined in ServletContext resource [/WEB-INF/spring/app-config.xml]: Instantiation of bean failed; nested exception is net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$301(AbstractDelegatedExecutionApplicationContext.java:60)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$1.run(AbstractDelegatedExecutionApplicationContext.java:168)
at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.normalRefresh(AbstractDelegatedExecutionApplicationContext.java:164)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$NoDependenciesWaitRefreshExecutor.refresh(AbstractDelegatedExecutionApplicationContext.java:78)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:157)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:384)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
at org.eclipse.gemini.web.tomcat.internal.TomcatServletContainer.startWebApplication(TomcatServletContainer.java:125)
at org.eclipse.gemini.web.internal.StandardWebApplication.start(StandardWebApplication.java:109)
at org.eclipse.virgo.web.core.internal.WebBundleLifecycleListener.onStarted(WebBundleLifecycleListener.java:122)
at org.eclipse.virgo.kernel.install.artifact.internal.StandardArtifactStateMonitor.onStarted(StandardArtifactStateMonitor.java:271)
at org.eclipse.virgo.kernel.install.artifact.internal.AbstractInstallArtifact.asyncStartSucceeded(AbstractInstallArtifact.java:319)
at org.eclipse.virgo.kernel.install.artifact.internal.AbstractInstallArtifact.access$0(AbstractInstallArtifact.java:316)
at org.eclipse.virgo.kernel.install.artifact.internal.AbstractInstallArtifact$StateMonitorSignal.signalSuccessfulCompletion(AbstractInstallArtifact.java:252)
at org.eclipse.virgo.nano.core.internal.BundleStartTracker$1.run(BundleStartTracker.java:140)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'router' defined in ServletContext resource [/WEB-INF/spring/app-config.xml]: Cannot create inner bean 'org.restlet.ext.spring.SpringFinder#5700078' of type [org.restlet.ext.spring.SpringFinder] while setting bean property 'attachments' with key [TypedStringValue: value [/data/dashboard/geppettoprojects], target type [null]]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.restlet.ext.spring.SpringFinder#5700078' defined in ServletContext resource [/WEB-INF/spring/app-config.xml]: Instantiation of bean failed; nested exception is net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:281)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:120)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedMap(BeanDefinitionValueResolver.java:378)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:161)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
... 38 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.restlet.ext.spring.SpringFinder#5700078' defined in ServletContext resource [/WEB-INF/spring/app-config.xml]: Instantiation of bean failed; nested exception is net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:997)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:943)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:270)
... 50 common frames omitted
Caused by: net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
at org.springframework.beans.factory.support.CglibSubclassingInstantiationStrategy$CglibSubclassCreator.instantiate(CglibSubclassingInstantiationStrategy.java:119)
at org.springframework.beans.factory.support.CglibSubclassingInstantiationStrategy.instantiateWithMethodInjection(CglibSubclassingInstantiationStrategy.java:71)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:990)
... 54 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
... 60 common frames omitted
Caused by: java.lang.NoClassDefFoundError: net/sf/cglib/proxy/Factory
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
... 66 common frames omitted
Caused by: org.eclipse.virgo.kernel.osgi.framework.ExtendedClassNotFoundException: net.sf.cglib.proxy.Factory in KernelBundleClassLoader: [bundle=org.restlet.ext.spring_2.2.3.v20141127-1706]
at org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader.loadClass(KernelBundleClassLoader.java:150)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 68 common frames omitted
Caused by: java.lang.ClassNotFoundException: net.sf.cglib.proxy.Factory
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader.loadClass(KernelBundleClassLoader.java:146)
... 69 common frames omitted
In fact, you don't necessary need the extension org.restlet.ext.osgi
to make work Restlet within an OSGi container. As a matter of fact, with the OSGi edition, all Restlet jars contain valid MANIFEST files (even before version 2.2).
Virgo supports Web bundles so you can embed a Restlet application in it leveraging the extension org.restlet.ext.servlet
. You can have a look at the following link for more details: https://github.com/restlet/restlet-tutorial/blob/master/modules/org.restlet.tutorial.markdown/02_Server_Side/04_Server_Deployment/02_Servlet_Deployment.md.
Otherwise I would be interested in having more details about the errors you have when trying to use Restlet in such context.
Edited (Following the new elements added in the question)
You should configure the Restlet servlet for Spring. This servlet would replace the one from Spring itself (DispatcherServlet
). The listener ContextLoaderListener
must remain since it's used to manage the Spring application context within the Web bundle.
Here is a sample of configuration for this servlet:
<servlet>
<servlet-name>SpringRestletServlet</servlet-name>
<servlet-class>org.restlet.ext.spring.SpringServerServlet</servlet-class>
<init-param>
<param-name>org.restlet.component</param-name>
<param-value>myComponent</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>tracker</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
The servlet will look for a bean named myComponent
in your Spring application context.
Here is a sample of configuration of Restlet within this application context:
<bean id="myComponent" class="org.restlet.ext.spring.SpringComponent">
<property name="defaultTarget" ref="router" />
</bean>
<bean name="router" class="org.restlet.ext.spring.SpringRouter">
<property name="attachments">
<map>
<entry key="/ping">
<bean class="org.restlet.ext.spring.SpringFinder">
<lookup-method name="create" bean="pingServerResource" />
</bean>
</entry>
<entry key="/dir" value-ref="staticsDirectory" />
</map>
</property>
</bean>
<bean id="pingServerResource" class="test.TestServerResource"></bean>