Используйте рестлет с Eclipse Virgo

Я пытаюсь интегрировать рестлет в приложение, используя Eclipse Virgo в качестве сервера приложений. Поскольку Virgo основана на OSGi, мне пришлось использовать библиотеки org.restlet.osgi и самую новую версию (restlet 2.2.3), которая не зависит от Java 1.7, потому что последний выпуск Virgo жалуется на пакеты, зависящие от Java 1.7.

Я пытаюсь заставить restlet использовать веб-сервер Eclipse Virgo для доставки REST API, но похоже, что все, что я пробовал, не работает. Конечно, я могу запустить собственный веб-сервер рестлета на отдельном порту, чем порт Eclipse Virgo, но мне не удалось использовать его веб-сервер. Это вообще возможно?

Обновить

В историю также вовлечена Весна, поэтому я думаю, что это сделает ее еще более интересной. Конфигурация, связанная с Spring, приведена ниже:

<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>

Теперь я получаю это исключение:

[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

person Dan D.    schedule 09.03.2015    source источник


Ответы (1)


На самом деле вам не нужно расширение org.restlet.ext.osgi, чтобы заставить Restlet работать в контейнере OSGi. На самом деле, в версии OSGi все jar-файлы Restlet содержат действительные файлы МАНИФЕСТА (даже до версии 2.2).

Virgo поддерживает веб-пакеты, поэтому вы можете встроить в него приложение Restlet, используя расширение org.restlet.ext.servlet. Вы можете просмотреть следующую ссылку для получения более подробной информации: https://github.com/restlet/restlet-tutorial/blob/master/modules/org.restlet.tutorial.markdown/02_Server_Side/04_Server_Deployment/02_Servlet_Deployment.md .

В противном случае мне было бы интересно получить более подробную информацию об ошибках, которые возникают у вас при попытке использовать Restlet в таком контексте.

Отредактировано (после добавления новых элементов в вопрос)

Вы должны настроить сервлет Restlet для Spring. Этот сервлет заменит сервлет из самой Spring (DispatcherServlet). Слушатель ContextLoaderListener должен остаться, поскольку он используется для управления контекстом приложения Spring в веб-пакете.

Вот пример конфигурации для этого сервлета:

<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>

Сервлет будет искать bean-компонент с именем myComponent в контексте вашего приложения Spring.

Вот пример конфигурации Restlet в этом контексте приложения:

<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>
person Thierry Templier    schedule 09.03.2015
comment
Спасибо за ваше объяснение. Я следовал учебнику, но без особого успеха. Вероятно, это потому, что мне нужно заставить все работать и с Spring. Я обновил вопрос, не могли бы вы взглянуть? - person Dan D.; 10.03.2015
comment
Я обновил свой ответ, чтобы описать, как настроить Restlet в вашем контексте. Надеюсь, это решит вашу проблему! - person Thierry Templier; 10.03.2015
comment
Я получаю это: Вызвано: java.lang.ClassNotFoundException: net.sf.cglib.proxy.Factory независимо от того, что я пытаюсь. Я знаю, что это особенность OSGi, но что бы я ни делал, чтобы он увидел зависимость cglib, у меня ничего не вышло. - person Dan D.; 10.03.2015
comment
Можете ли вы предоставить полный стек исключений, чтобы увидеть, откуда они выбрасываются? Спасибо! - person Thierry Templier; 10.03.2015
comment
Я обновил вопрос, так как не смог поместить в комментарий всю трассировку стека. - person Dan D.; 10.03.2015
comment
Спасибо! У вас есть пакет net.sf.cglib в вашем контейнере osgi? Правильно ли он запущен? - person Thierry Templier; 10.03.2015
comment
Я пробовал разные версии OSGified cglib бандлов: com.springsource.net.sf.cglib, org.apache.servicemix.bundles.cglib,... Я добавил пакет импорта для всех пакетов в бандлах. У меня закончились идеи. - person Dan D.; 10.03.2015
comment
Что бы я попробовал проверить: - правильно ли установлен/запущен пакет cglib в контейнере osgi? - выяснить, какой пакет импортирует его. - проверьте, совпадают ли версии (экспорт и импорт) - попробуйте последнюю версию весны - person Thierry Templier; 10.03.2015
comment
Я знаю, что если я не импортирую пакеты cglib, он жалуется на класс CallbackFilter. Если я их импортирую, он жалуется на Factory, которая находится в том же пакете, что и CallbackFilter. Так что я думаю, что пакет установлен. Я вижу, что люди исправили это, обновив до Spring 3.2, но, к сожалению, у меня нет такой роскоши. - person Dan D.; 10.03.2015
comment
Возможно, проблема в файле МАНИФЕСТА Spring. Вы можете попробовать восстановить его с помощью Bnd. Это также может быть проблемой в исходном коде Spring :-( Такие проблемы утомительно исправлять. Какую версию Spring вы используете? - person Thierry Templier; 10.03.2015
comment
Я принял ваше решение, так как уверен, что оно обычно работает, но не в моей среде. Большое спасибо за ваши усилия. - person Dan D.; 11.03.2015