java 如何将 Jersey 与 TomEE / openEJB 集成
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10583563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I integrate Jersey with TomEE / openEJB
提问by Greg
I am upgrading a code that uses Jersey JAX-RS to run on an Apache TomEE server. Unfortunately it throws errors when I try to use Jersey with TomEE.
我正在升级使用 Jersey JAX-RS 在 Apache TomEE 服务器上运行的代码。不幸的是,当我尝试将 Jersey 与 TomEE 一起使用时它会引发错误。
I am using eclipse and have the JAX-RS project facet turned on. It points to the Jersey library. I have also moved the Jersey libraries into the /lib/ directory to try to solve the problem to no avail. The server throws the following error:
我正在使用 eclipse 并打开了 JAX-RS 项目方面。它指向泽西图书馆。我也把Jersey库移到/lib/目录下尝试解决问题无果。服务器抛出以下错误:
May 14, 2012 6:26:44 AM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Provider classes found:
class org.codehaus.Hymanson.jaxrs.JsonParseExceptionMapper
class org.codehaus.Hymanson.jaxrs.HymansonJaxbJsonProvider
class org.codehaus.Hymanson.jaxrs.JsonMappingExceptionMapper
class org.codehaus.Hymanson.jaxrs.HymansonJsonProvider
May 14, 2012 6:26:44 AM org.apache.catalina.core.ApplicationContext log
SEVERE: StandardWrapper.Throwable
java.lang.RuntimeException: javax.naming.NameNotFoundException: Name [com] is not bound in this Context. Unable to find [com].
at com.sun.jersey.server.impl.cdi.CDIExtension.getInitializedExtension(CDIExtension.java:177)
at com.sun.jersey.server.impl.cdi.CDIComponentProviderFactory.<init>(CDIComponentProviderFactory.java:92)
at com.sun.jersey.server.impl.cdi.CDIComponentProviderFactoryInitializer.initialize(CDIComponentProviderFactoryInitializer.java:75)
at com.sun.jersey.spi.container.servlet.WebComponent.configure(WebComponent.java:576)
at com.sun.jersey.spi.container.servlet.ServletContainer$InternalWebComponent.configure(ServletContainer.java:311)
at com.sun.jersey.spi.container.servlet.WebComponent.load(WebComponent.java:608)
at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:210)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:373)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:556)
at javax.servlet.GenericServlet.init(GenericServlet.java:160)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1266)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1185)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1080)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5015)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5302)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.naming.NameNotFoundException: Name [com] is not bound in this Context. Unable to find [com].
at org.apache.naming.NamingContext.lookup(NamingContext.java:820)
at org.apache.naming.NamingContext.lookup(NamingContext.java:168)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:158)
at javax.naming.InitialContext.lookup(Unknown Source)
at com.sun.jersey.server.impl.cdi.CDIExtension.stepInto(CDIExtension.java:290)
at com.sun.jersey.server.impl.cdi.CDIExtension.diveIntoJNDIContext(CDIExtension.java:267)
at com.sun.jersey.server.impl.cdi.CDIExtension.lookupJerseyConfigJNDIContext(CDIExtension.java:287)
at com.sun.jersey.server.impl.cdi.CDIExtension.getInitializedExtension(CDIExtension.java:175)
... 22 more
web.xml:
网页.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>tomeeTest3</display-name>
<servlet>
<description>JAX-RS Tools Generated - Do not modify</description>
<servlet-name>JAX-RS Servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS Servlet</servlet-name>
<url-pattern>/jaxrs/*</url-pattern>
</servlet-mapping>
</web-app>
Does anyone know how I might make this work? I'd also consider using the tomEE+ Jax-rs server, but it doesn't seem to recognize the Hymanson annotations.
有谁知道我如何使这项工作?我还考虑使用 tomEE+ Jax-rs 服务器,但它似乎无法识别 Hymanson 注释。
EDIT: I think the issue is that the openEJB CDI is conflicting with the CDI that comes with Jersey. I have no idea how to fix this.
编辑:我认为问题在于 openEJB CDI 与 Jersey 附带的 CDI 冲突。我不知道如何解决这个问题。
回答by grauwulf
RESURRECTION! Just in case anyone is still running into this problem.
复活!以防万一有人仍然遇到这个问题。
I had a Jersey application that was running in Tomcat peachy keen and exploded in exactly this manner when I moved it it TomEE. The problem is that TomEE already has its own JAX-RS implementation (tomee-jaxrs-1.5.0 at the time of this writing), which conflicts with the jersey-bundle jars.
我有一个 Jersey 应用程序,它在 Tomcat 中运行,当我将它移动到 TomEE 时,它以这种方式爆炸。问题是 TomEE 已经有自己的 JAX-RS 实现(在撰写本文时,tomee-jaxrs-1.5.0)与 jersey-bundle jar 冲突。
All I had to do to get rid of this problem was remove the jersey jars and comment out the servlet declaration and mapping in the web.xml
为了摆脱这个问题,我所要做的就是删除球衣罐并注释掉 web.xml 中的 servlet 声明和映射
Give it a restart, and viola! Just remember that the URLs will be slightly different. For example, on a default jersey install you might have http://localhost/rest/represent/me
and when you move that same app to TomEE it will be http://localhost/represent/me
重新启动它,中提琴!请记住,URL 会略有不同。例如,在默认 jersey 安装中,您可能有http://localhost/rest/represent/me
,当您将同一个应用程序移动到 TomEE 时,它将是http://localhost/represent/me
If you're using an IDE like eclipse it might bark at you for not being able to find the jars, just go into the project properties and set the target runtime to TomEE (you will have to add a server instance) and you should be good to go.
如果您使用的是 Eclipse 之类的 IDE,它可能会因为找不到 jars 而对您吠叫,只需进入项目属性并将目标运行时设置为 TomEE(您必须添加一个服务器实例),您应该很高兴去。
Share and enjoy.
分享和享受。
回答by pickypg
I too have run into this problem with that exact exception, and unfortunately grauwulf's answer did not work for me.
我也遇到了这个确切的例外问题,不幸的是 grauwulf 的回答对我不起作用。
In my case, I have Tomee+ 1.5.2, Jersey 1.1x, and I am also using Spring 3.x.
就我而言,我有 Tomee+ 1.5.2、Jersey 1.1x,而且我也在使用 Spring 3.x。
The fix was actually quite simple:
修复实际上非常简单:
- Find the Tomee
system.properties
file ({tomee}/conf/system.properties
by default). - Add
com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager=true
- 找到 Tomee
system.properties
文件({tomee}/conf/system.properties
默认情况下)。 - 添加
com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager=true
From there, it just worked for me. To give the credit where it's due, I found it on this blog post.
从那里开始,它对我有用。为了给予应有的荣誉,我在这篇博文中找到了它。
Of interest, I also prefer to avoid cluttering my {tomee}/lib
folder with my war's dependencies, so I have also found that you can easily add an extra lib by modifying {tomee}/conf/tomee.xml
, and adding the following node (inside the root <tomee />
node):
有趣的是,我也更喜欢避免我的{tomee}/lib
文件夹与我的War依赖项混淆,所以我还发现您可以通过修改 轻松添加额外的库{tomee}/conf/tomee.xml
,并添加以下节点(在<tomee />
根节点内):
<tomee>
<Service
id="extra-libs-enricher"
class-name="org.apache.openejb.assembler.classic.enricher.AdditionalLibClassLoaderEnricherObserver">
path = /path/to/your/libs
</Service>
</tomee>
With that Service
, whose name is arbitrary, you can notpass a path
, at which point it defaults to "additional-lib"
. The passed in path will be used by default, but if it is not a directory, then it will fall back to a system property, which can be added to the system.properties
file. The system property is: openejb.enricher.additional-lib
.
有了它Service
,其名称是任意的,您不能传递 a path
,此时它默认为"additional-lib"
。默认会使用传入的路径,但如果它不是目录,那么它将回退到系统属性,可以将其添加到system.properties
文件中。系统属性是:openejb.enricher.additional-lib
。
openejb.enricher.additional-lib=/fallback/path/to/your/libs
This system property is only checked if the path passed to Service
, or its default value, does not work andonly if a Service
is placed in the tomee.xml
file. Its id
is irrelevant.
仅当传递给 的路径Service
或其默认值不起作用且仅当 aService
放置在tomee.xml
文件中时,才会检查此系统属性。它id
无关紧要。
回答by emgsilva
Just came across with this problem: TomEE + Jersey... the problem was that I was using TomEE in Eclipse "Use workspace metadata"... and somehow when configured like this the server configurations misses several details of the TomEE configs (namely the conf/system.properties - where we declare: "com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager=true"). When I changed it to "Use Tomcat installation", the problem went away. You can configure this by double-clicking the TomEE server in Eclipse and select "Use Tomcat installation", as seen in the following image:
刚刚遇到这个问题: TomEE + Jersey ... conf/system.properties - 我们声明:“com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager=true”)。当我将其更改为“使用 Tomcat 安装”时,问题就消失了。您可以通过在 Eclipse 中双击 TomEE 服务器并选择“使用 Tomcat 安装”来进行配置,如下图所示:
回答by Chris Hinshaw
I traced it down and pickypg is correct. I was able to get this to work with TomEE 1.5.2 using the tomee-maven-plugin. I haven't figured out exactly, but this problem occurs after the jersey figures out there is a bean manager at java:comp/BeanManager and tries to lookup the context.
我追查下来,pickypg 是正确的。我能够使用 tomee-maven-plugin 让它与 TomEE 1.5.2 一起使用。我还没有完全弄清楚,但是在 jersey 发现 java:comp/BeanManager 中有一个 bean 管理器并尝试查找上下文之后,就会出现这个问题。
<plugin>
<groupId>org.apache.openejb.maven</groupId>
<artifactId>tomee-maven-plugin</artifactId>
<version>1.0.1</version>
<configuration>
<tomeeHttpPort>${http.port}</tomeeHttpPort>
<tomeeVersion>1.5.2</tomeeVersion>
<args>-Dcom.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager=true</args>
</configuration>
</plugin>
Here are the excerts of jersey where it is running into the issue.
以下是球衣的 excerts 遇到问题的地方。
public CDIComponentProviderFactory(Object bm, ResourceConfig rc, WebApplication wa) {
beanManager = (BeanManager)bm;
// work around proxying bug in Weld
if (CDIExtension.lookupExtensionInBeanManager) {
extension = Utils.getInstance(beanManager, CDIExtension.class);
}
else {
// NOTE THIS IS WHAT IS BEING EXECUTED WHEN FLAG IS SET TO FALSE
extension = CDIExtension.getInitializedExtension();
}
extension.setWebApplication(wa);
extension.setResourceConfig(rc);
}
/*
* Returns the instance of CDIExtension that was initialized previously in this same thread, if any.
*/
public static CDIExtension getInitializedExtension() {
try {
InitialContext ic = InitialContextHelper.getInitialContext();
if (ic == null) {
throw new RuntimeException();
}
return (CDIExtension)lookupJerseyConfigJNDIContext(ic).lookup(JNDI_CDIEXTENSION_NAME);
} catch (NamingException ex) {
throw new RuntimeException(ex);
}
}
...
...
/*
* Setting this system property to "true" will force use of the BeanManager to look up the bean for the active CDIExtension,
* rather than going through a thread local.
*/
private static final String LOOKUP_EXTENSION_IN_BEAN_MANAGER_SYSTEM_PROPERTY = "com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager";
public static final boolean lookupExtensionInBeanManager = getLookupExtensionInBeanManager();
private static boolean getLookupExtensionInBeanManager() {
return Boolean.parseBoolean(System.getProperty(LOOKUP_EXTENSION_IN_BEAN_MANAGER_SYSTEM_PROPERTY, "false"));
}
回答by AIMABLE
I was able to do that and if someone is looking for the solution that's what i did
我能够做到这一点,如果有人正在寻找解决方案,那就是我所做的
This what i did: * i'm using NetBeans 7.3.1 * I added the following lines in Tomee\conf\system.properties –>com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager= true * I added jersey libraries from NetBeans that's all * Note that the libraries are in WEB-INF\lib of my apps * Additional information i was even able to use Mojarra for JSF if someone is interested i can tell you how
这是我所做的: * 我使用的是 NetBeans 7.3.1 * 我在 Tomee\conf\system.properties 中添加了以下几行 –>com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager= true * 我添加了 jersey 库来自 NetBeans 就是这样 * 请注意,这些库位于我的应用程序的 WEB-INF\lib 中 * 附加信息 如果有人感兴趣,我什至可以将 Mojarra 用于 JSF 我可以告诉你如何
回答by Eugenio Cuevas
You should add the package of the Provider classes as a parameter to the servlet:
您应该将 Provider 类的包作为参数添加到 servlet:
<servlet>
<servlet-name>ServletAdaptor</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>your.package.name</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/jaxrs/*</url-pattern>
</servlet-mapping>
Your provider classes should look like this:
您的提供程序类应如下所示:
package your.package.name;
@Path("/test")
public class StatsServlet {
@PUT
@Produces(MediaType.TEXT_HTML)
public String doPutHtml() {
return "Hello!";
}
}