使用Jetty启动Jersey应用程序 [英] Start Jersey application with Jetty
问题描述
我在Ubuntu服务器VCS中安装了jetty 9服务器. Java Rest项目的结构:
I install jetty 9 server in my Ubuntu server VCS. Structure of java rest project:
/opt/jetty/webapps/backend/
/opt/jetty/webapps/backend /
- 构建
- conf
- lib
- 库
- 日志
- src/com/example/package/backend
- 资源
- CategoryResource.java
- build
- conf
- lib
- libs
- logs
- src/com/example/package/backend
- resources
- CategoryResource.java
- WEB-INF
- web.xml
- WEB-INF
- web.xml
BackendServer.java
BackendServer.java
import com.sun.jersey.api.container.httpserver.HttpServerFactory; import com.sun.jersey.api.core.PackagesResourceConfig; import com.sun.net.httpserver.HttpServer; public class BackendServer { public static void main(String[] args) throws IOException { HttpServer server = HttpServerFactory.create("http://localhost:" + "8080" + "/" + "backend/rest", new PackagesResourceConfig("com.droidbrew.androcommerce.backend.resources")); DbManager.getInstance(); server.start(); System.out.println("Server running"); System.out.println("Hit return to stop..."); System.in.read(); System.out.println("Stopping server"); server.stop(0); System.out.println("Server stopped"); } }
CategoryResource.java
CategoryResource.java
Path("/category") public class CategoryResource { @GET @Path("/get_all_categories") @Produces({MediaType.APPLICATION_JSON}) public String getAllCategories() throws SQLException { List<Category> categoryList = DbManager.getInstance().getBackendCategoryManager().getAllCategories(); Gson gson = new Gson(); return gson.toJson(categoryList); } }
web.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_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>Jersey</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <servlet> <servlet-name>Jersey REST Service</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>com.droidbrew.androcommerce.backend.resources</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey REST Service</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app>
/opt/jetty/webapps/backend.xml
/opt/jetty/webapps/backend.xml
<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"> <Configure class="org.mortbay.jetty.webapp.WebAppContext"> <Set name="configurationClasses"> <Array type="java.lang.String"> <Item>org.mortbay.jetty.webapp.WebInfConfiguration</Item> <Item>org.mortbay.jetty.plus.webapp.EnvConfiguration</Item> <Item>org.mortbay.jetty.plus.webapp.Configuration</Item> <Item>org.mortbay.jetty.webapp.JettyWebXmlConfiguration</Item> <Item>org.mortbay.jetty.webapp.TagLibConfiguration</Item> </Array> </Set> <Set name="contextPath">/</Set> <Set name="resourceBase"><SystemProperty name="jetty.home" default="."/>/webapps/backend</Set> <New id="development" class="org.mortbay.jetty.plus.naming.Resource"> <Arg>jdbc/development</Arg> <Arg> <New class="org.postgresql.ds.PGConnectionPoolDataSource"> <Set name="User">user</Set> <Set name="Password">1111</Set> <Set name="DatabaseName">development</Set> <Set name="ServerName">localhost</Set> <Set name="PortNumber">5432</Set> </New> </Arg> </New> </Configure>
但是在我启动
service jetty start
并尝试连接ip:8085/backend/rest/category/get_all_categories
之后,我得到了:But after I start
service jetty start
and try connectip:8085/backend/rest/category/get_all_categories
I get:HTTP错误:404
问题访问/backend/rest/category/get_all_categories. 原因:
Problem accessing /backend/rest/category/get_all_categories. Reason:
未找到
更新
java -DDEBUG -jar start.jar
sudo java -DDEBUG -jar start.jar System Property [DEBUG] has been deprecated! (Use org.eclipse.jetty.LEVEL=DEBUG instead) 2014-10-06 13:09:09.522:INFO::main: Logging initialized @1090ms ShutdownMonitor not in use (port < 0): -1 2014-10-06 13:09:10.047:INFO:oejs.Server:main: jetty-9.2.3.v20140905 2014-10-06 13:09:10.073:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/opt/jetty/webapps/] at interval 1 2014-10-06 13:09:10.096:WARN:oejd.DeploymentManager:main: Unable to reach node goal: started java.lang.ClassNotFoundException: org.mortbay.jetty.webapp.WebAppContext at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) at org.eclipse.jetty.util.Loader.loadClass(Loader.java:86) at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.nodeClass(XmlConfiguration.java:364) at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.configure(XmlConfiguration.java:304) at org.eclipse.jetty.xml.XmlConfiguration.configure(XmlConfiguration.java:262) at org.eclipse.jetty.deploy.providers.WebAppProvider.createContextHandler(WebAppProvider.java:291) at org.eclipse.jetty.deploy.App.getContextHandler(App.java:101) at org.eclipse.jetty.deploy.bindings.StandardDeployer.processBinding(StandardDeployer.java:36) at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:186) at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:498) at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:146) at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:180) at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:64) at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:609) at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:528) at org.eclipse.jetty.util.Scanner.scan(Scanner.java:391) at org.eclipse.jetty.util.Scanner.doStart(Scanner.java:313) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.deploy.providers.ScanningAppProvider.doStart(ScanningAppProvider.java:150) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.deploy.DeploymentManager.startAppProvider(DeploymentManager.java:560) at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:235) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132) at org.eclipse.jetty.server.Server.start(Server.java:387) at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114) at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61) at org.eclipse.jetty.server.Server.doStart(Server.java:354) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1255) at java.security.AccessController.doPrivileged(Native Method) at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1174) 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 org.eclipse.jetty.start.Main.invokeMain(Main.java:310) at org.eclipse.jetty.start.Main.start(Main.java:786) at org.eclipse.jetty.start.Main.main(Main.java:111) 2014-10-06 13:09:10.111:WARN:oejuc.AbstractLifeCycle:main: FAILED ServerConnector@1d402894{HTTP/1.1}{0.0.0.0:8080}: java.net.BindException: Address already in use java.net.BindException: Address already in use at sun.nio.ch.Net.bind0(Native Method) at sun.nio.ch.Net.bind(Net.java:444) at sun.nio.ch.Net.bind(Net.java:436) at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214) at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74) at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:320) at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80) at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:236) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.server.Server.doStart(Server.java:366) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1255) at java.security.AccessController.doPrivileged(Native Method) at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1174) 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 org.eclipse.jetty.start.Main.invokeMain(Main.java:310) at org.eclipse.jetty.start.Main.start(Main.java:786) at org.eclipse.jetty.start.Main.main(Main.java:111) 2014-10-06 13:09:10.114:WARN:oejuc.AbstractLifeCycle:main: FAILED org.eclipse.jetty.server.Server@5f281b8c: java.net.BindException: Address already in use java.net.BindException: Address already in use at sun.nio.ch.Net.bind0(Native Method) at sun.nio.ch.Net.bind(Net.java:444) at sun.nio.ch.Net.bind(Net.java:436) at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214) at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74) at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:320) at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80) at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:236) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.server.Server.doStart(Server.java:366) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1255) at java.security.AccessController.doPrivileged(Native Method) at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1174) 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 org.eclipse.jetty.start.Main.invokeMain(Main.java:310) at org.eclipse.jetty.start.Main.start(Main.java:786) at org.eclipse.jetty.start.Main.main(Main.java:111) java.lang.reflect.InvocationTargetException 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 org.eclipse.jetty.start.Main.invokeMain(Main.java:310) at org.eclipse.jetty.start.Main.start(Main.java:786) at org.eclipse.jetty.start.Main.main(Main.java:111) Caused by: java.net.BindException: Address already in use at sun.nio.ch.Net.bind0(Native Method) at sun.nio.ch.Net.bind(Net.java:444) at sun.nio.ch.Net.bind(Net.java:436) at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214) at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74) at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:320) at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80) at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:236) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.server.Server.doStart(Server.java:366) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1255) at java.security.AccessController.doPrivileged(Native Method) at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1174) ... 7 more
推荐答案
您的XML文件引用了旧版本的Jetty.
Your XML files are referencing an old version of Jetty.
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
org.mortbay.jetty
名称空间适用于Jetty 6或更旧的Jetty版本(所有这些版本都已经退出EOLd多年了).The
org.mortbay.jetty
namespace is for Jetty 6 or older versions of Jetty, (all of which have been EOLd for years now).Jetty 9的整个XML文档都是错误的,从DOCTYPE到类引用,甚至是结构.
That entire XML document is wrong for Jetty 9, from the DOCTYPE, to the class references, even to the structure.
<SystemProperty>
元素引用一个在码头嵌入式中未使用的"jetty.home"
变量(该变量仅用于码头分布,也称为start.jar).jetty-http-spi.jar
甚至没有设置或使用此属性.The
<SystemProperty>
element references a"jetty.home"
variable that isn't used in jetty embedded (its only there for the jetty distribution, aka start.jar). Thejetty-http-spi.jar
doesn't even set or use this property.jetty-deploy.jar
提供了使用Jetty上下文XML可部署的功能,但是com.sun.net.httpserver.HttpServer
概念不支持这种可部署的功能,它们是独立的可部署的,还是内部的WEB-INF/jetty-web.xml
配置.The use of the Jetty Context XML Deployable is a feature that
jetty-deploy.jar
provides, however, that sort of deployable is not supported by thecom.sun.net.httpserver.HttpServer
concepts, either as a standalone deployable, or an internalWEB-INF/jetty-web.xml
configuration.您尝试设置的整个后端服务器大战只能在您开始的
com.sun.net.httpserver.HttpServer
上使用(基本概念上不受该概念支持)That whole backend server war you are attempting to setup just cannot be on the
com.sun.net.httpserver.HttpServer
you started (not supported by that concept at a fundamental level)不幸的是,当您使用
com.sun.net.httpserver.HttpServer
技术时,几乎没有可用的故障排除方法.几乎仅限于日志输出.Unfortunately, there is almost no troubleshooting available when you use the
com.sun.net.httpserver.HttpServer
techniques. Pretty much limited to logging output.记录输出显示什么?
更新时间:2014年10月7日:
关于日志输出,让我们看看.
About the logging output, lets see.
您正在使用Jetty 9.2.3发行版通过命令行启动码头.
You are starting jetty via command line, using the Jetty 9.2.3 distribution.
该行为与您
BackendServer
对com.sun.net.httpserver.HttpServer
的使用完全无关.That act is completely unrelated to your
BackendServer
use ofcom.sun.net.httpserver.HttpServer
.这将导致2台不同的服务器.
This would result in 2 different servers.
- 独立的Jetty 9.2.3分发服务器
-
com.sun.net.httpserver.HttpServer
服务器
- The standalone Jetty 9.2.3 distribution server
- The
com.sun.net.httpserver.HttpServer
server
这些日志中基本上显示2个错误.
You have essentially 2 errors showing in those logs.
首先是...
java.lang.ClassNotFoundException: org.mortbay.jetty.webapp.WebAppContext
那是因为您在Jetty 9中使用了Jetty 6技术.Jetty9中不存在该类(实际上是程序包名称空间).
That's because you are using Jetty 6 techniques for Jetty 9. That class (actually package namespace) doesn't exist in Jetty 9.
该类(在Jetty 9中)将称为在Eclipse Jetty文档网站上配置特定的Web应用程序部署以获取详细信息.
That class (in Jetty 9) would be called
org.eclipse.jetty.webapp.WebAppContext
, see Configuring a Specific Web App Deployment in the Eclipse Jetty documentation website for details.您将不得不分析和调整示例XML文件中的大多数内容,以适应自Jetty 6和Jetty 9以来近200个发行版的实际情况.Jetty6和Jetty 9之间已经花费了太多的时间来列出已更改的内容.这将等同于列出福特Model 18和特斯拉Model S之间的差异(这将是一个庞大的清单,从本质上讲意味着一切",无济于事)
You will have to analyze and adjust most things in your example XML file to fit the realities of the nearly 200 releases since Jetty 6 and Jetty 9. Far too much time has elapsed between Jetty 6 and Jetty 9 to list what has changed. It would be equivalent to listing the differences between a Ford Model 18 and a Tesla Model S (it would be a huge list that would essentially mean 'everything' and be useless to work off of)
另一个错误...
FAILED ServerConnector@1d402894{HTTP/1.1}{0.0.0.0:8080}: java.net.BindException: Address already in use
意味着该服务器无法绑定到端口8080,因为其他服务器已经存在.
means that this server cannot bind to port 8080, as some other server is already there.
这很有意义,因为您的
BackendServer
也在端口8080上(根据您的示例代码).This makes sense, as your
BackendServer
is also on port 8080 (per your example code).不要试图将嵌入式码头和
com.sun.net.httpserver.HttpServer
混在一起,只会试图强迫com.sun.net.httpserver.HttpServer
做自己想做的事情.Don't try to mix embedded-jetty and
com.sun.net.httpserver.HttpServer
, you will only tear your hair out trying to forcecom.sun.net.httpserver.HttpServer
into doing what you want.考虑使用直接嵌入式码头+球衣servlet.
Consider using straight embedded-jetty + jersey servlet instead.
在线和StackOverflow中都有很多这种技术的示例.
There's lots of examples of this technique online and in StackOverflow.
这是我发现的第一个示例代码,该示例代码显示了如何为球衣
ServletContainer
设置ServletHolder
以及一些相关的初始化参数来进行配置. 配置球衣+码头+ JSPHere's the first one I found that had example code showing how to setup the
ServletHolder
for the jerseyServletContainer
along with some relevant init parameters to configure it. Configuring Jersey + Jetty + JSP这篇关于使用Jetty启动Jersey应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- resources
- 资源