Running Jetty and jWebSocket concurrently - java

I have used Jetty in the past but I have little experience with jWebSocket. I would like to add to my current program, which uses the Jetty libraries, and make it also support WebSocket connections though port 80. I have read it can be done but find little to no source or examples to read about it. Any help is appreciated.

I am currently working on the same thing, and so far I have found their task for this on Google Code:
http://code.google.com/p/jwebsocket/issues/detail?id=76
This was posted back in April of 2011:
"There's a separate project jWebSocketJetty available now in the Downloads / Nightly Build Section of jWebSocket.org now."
If you pull up the web.xml from that project, it looks like they've gotten their jwebsocket servlet working with jetty. I'll be looking into this more tomorrow.

You have to modify two configuration files to run jWebSocket on jetty using port 80.
1:- Modify your jWebSocket.xml and add jetty engine entry at top of engine section of xml.
<engines>
<engine>
<name>org.jwebsocket.jetty.JettyEngine</name>
.
.
</engine>
</engines>
You can delete all other engine entries.
2:- Modify jetty.xml. This file can be located at jWebSocketJetty\src\main\resources folder.
Modify first connector entry and set jetty.port property to 80.
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<Set name="host">
<Property name="jetty.host" />
</Set>
<!-- Jetty default -->
<!--
<Set name="port">
<Property name="jetty.port" default="80"/>
</Set>
-->
<!-- jWebSocket default, can be changed to 80 -->
<!-- but consider to update jWebSocket.js accordingly! -->
<Set name="port">
<Property name="jetty.port" default="80"/>
</Set>
<Set name="maxIdleTime">300000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
<Set name="confidentialPort">443</Set>
<Set name="lowResourcesConnections">20000</Set>
<Set name="lowResourcesMaxIdleTime">5000</Set>
<Set name="responseBufferSize">65536</Set>
</New>
</Arg>
</Call>

I don't know, because I haven't used it, but would their JettyServlet would work?

Related

maven jetty error 'Config error at <Set name="ThreadPool">'

I'm trying to configure a jetty-servlet in java using maven. I've create a jetty.xml file with the following entries
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Set name="ThreadPool">
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="minThreads">10</Set>
<Set name="maxThreads">200</Set>
<Set name="detailedDump">false</Set>
</New>
</Set>
</Configure>
upon running the server
mvn jetty:run
I see the error
[WARNING] Config error at <Set name="ThreadPool">
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool"><Set
name="minThreads">10</Set><Set name="maxThreads">200</Set><Set
name="detailedDump">false</Set></New>
</Set>
but cannot figure out what the problem actually is. I've also included jetty-util as a dependency in the pom.xml file. I'm using jetty version 9.4.12.v20180830 and java 8. Thanks for any help!
ThreadPool is a constructor argument for Server.
See: Javadoc for org.eclipse.jetty.server.Server
It's not a field and/or setter on Server, so you cannot use the <Set name="ThreadPool"> syntax.
Instead of replacing the threadpool, just "Get" the existing one and change settings on it.
Eg:
<Get name="ThreadPool">
<Set name="minThreads" type="int">10</Set>
<Set name="maxThreads" type="int">200</Set>
<Set name="detailedDump">false</Set>
</Get>

How can I make application use both SSL and TLS

Our java application presently uses SSL for communication between client and server using https. Customer requested if an upgrade can be done to TLS and if they can use both TLS and SSL at different locations. I cant understand clearly how to answer their questions or how to proceed.
jetty-ssl.xml file is as follows :
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<!-- =============================================================== -->
<!-- Configure SSL for the Jetty Server -->
<!-- this configuration file should be used in combination with -->
<!-- other configuration files. e.g. -->
<!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
<!-- =============================================================== -->
<Configure id="Server" class="org.mortbay.jetty.Server">
<Call name="addConnector">
<Arg>
<New class="org.mortbay.jetty.security.SslSocketConnector">
<Set name="Port">8443</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="handshakeTimeout">2000</Set>
<Set name="keystore">/xservices-config/keystore</Set>
<Set name="password">password</Set>
<Set name="keyPassword">password</Set>
<Set name="truststore">/keystore</Set>
<Set name="trustPassword">password</Set>
<Set name="handshakeTimeout">2000</Set>
<!-- Set name="ThreadPool">
<New class="org.mortbay.thread.BoundedThreadPool">
<Set name="minThreads">10</Set>
<Set name="maxThreads">250</Set>
</New>
</Set -->
</New>
</Arg>
</Call>
</Configure>
Please let me know how to implement it.
Are you sure you need to "enable" this? I just went back at the jetty documentation and figured, as long as you don't exclude a protocol, you're allowing them all. Check your installation either with a local tool (sslscan, nmap, etc.) or a web application (e.g. from Qualys or COMODO).
If you find with the above analysis that you don't have the versions running, you could use an Apache webserver as HTTPS end-point and mod_proxy the content to jetty.
If that above is your SSL configuration for jetty, I strongly recommend you to harden it! Exclude legacy SSL protocols (e.g. SSLv2) and weak ciphers! As others have mentioned SSLv3 is actually legacy as well and not recommended anymore. In your position, I would get back to your client and check why he wants to have SSLv3 running. Unless he isn't expecting connections from dead old systems (e.g. Win XP with IE), there is not much of a reason to have SSLv3 running. However, if he does not know who is connecting to his page with what browsers, have a look at the logs. If the logs don't show an indication of the web browser used to connect to the application, I strongly recommend to enable it, run it for a period and then take a decision.

Jetty.xml import local class

I have a web-app that i run through Maven Jetty plugin.
I configure it using a jetty.xml file. My problem comes when i want to set a custom authenticator that i have created in the WebAppContext. The XML config looks like below:
<New id="webAppContext" class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/</Set>
<Set name="copyWebDir">true</Set>
<Set name="extractWAR">false</Set>
</Set>
<Get name="securityHandler">
<Set name="authenticator">
<New class="MY_CUSTOM_AUTHENTICATOR">
</New>
</Set>
</Get>
</New>
When i run the above i get a ClassNotFoundException for "MY_CUSTOM_AUTHENTICATOR" class. I have to add that the class exists in the same maven project that i launch Jetty from.
Is there an "import" statement that i have to do in order for Jetty to load my class?
Thank you.
You most likely need to have your authenticator in an artifact that is then declared as a dependency of the jetty maven plugin itself. With classloader isolation in play the authenticator is probably in your webapp where the security handler does not have visibility.

How to configure Jetty to reload a WebAppContext when classes are changed

I'm developing a web application and I run Jetty as the development and testing environment when I develop under Eclipse.
When I make changes to Java classes, Eclipse automatically compiles them to the build directory, but Jetty won't see the changes until I stop and start the server. I know that Jetty supports "hot deployment" using ContextDeployer that will refresh updated application contexts, but it relies on a context file in a context directory being updated - which is not very useful in my case.
Is there a way to set up Jetty so that it will reload the web app when any of the classes it uses is updated?
My current jetty.xml looks something like this:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Set name="ThreadPool"><!-- bla bla --></Set>
<Call name="addConnector"><!-- bla bla --></Call>
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<New id="webapp" class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="displayName">My Web App</Set>
<Set name="resourceBase">src/main/webapp</Set>
<Set name="descriptor">src/main/webapp/WEB-INF/web.xml</Set>
<Set name="contextPath">/mywebapp</Set>
</New>
</Item>
<Item>
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
</Configure>
We have not found a way of doing this (aside from implementing our own version of the org.eclipse.jetty.deploy.providers.WebAppProvider).
We have configured jetty to hot deploy webapps from the webapps folder (property monitoredDirName of the WebappDeployer).
Then to hot deploy, I recreate my link in this folder to the src/main/webapp folder of my Eclipse project. The linked must be suffixed .war.
Not really automatic but good enough and avoids a Jetty restart.
If you go the route of re-implementing a WebappDeployer, I would not monitor the changes in .class files - they change too much when compiled by Eclipse, particularly in the case of automatic builds. I would implement a 'Tomcat like' solution by monitoring changes to the web.xml file. Then a dummy change saved to this file from Eclipse would trigger a redeployment.
It is also possible to configure your jetty app with maven and starting periodical builds with Jenkins (even every couple of seconds, depending on the maschine you are working on)

JNDI lookup failed (NameNotFoundException)

UPDATE: Well, it seems that this is a problem only when I try to debug locally. When published on Jetty (not the same machine) it works great. Is it possible to configure the jetty.xml file used by Run-Jetty-Run when debugging locally?
I just wasted an afternoon trying to find the cause of this, but with no success...
I'm setting up a connection pool with c3p0 for my application. I'm using Jetty 7, by the way. The problem is that when I do a context.lookup get a datasource, I get this exception:
javax.naming.NameNotFoundException; remaining name 'env/jdbc/DSTest'
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:634)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:665)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:680)
at org.eclipse.jetty.jndi.java.javaRootURLContext.lookup(javaRootURLContext.java:113)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at com.see.metrics.SqlHelper.Initialize(SqlHelper.java:68)
at com.see.metrics.Metrics.Initialize(Metrics.java:45)
at com.see.game.GameProducer.generateMetadata(GameProducer.java:223)
at org.odata4j.producer.mongodb.MongoProducer.initMongo(MongoProducer.java:98)
at org.odata4j.producer.mongodb.MongoProducerFactory.create(MongoProducerFactory.java:55)
at org.odata4j.producer.resources.ODataProducerProvider.newProducerFromFactory(ODataProducerProvider.java:66)
at org.odata4j.producer.resources.ODataProducerProvider.getInstance(ODataProducerProvider.java:48)
at org.odata4j.producer.resources.ODataProducerProvider.getInstance(ODataProducerProvider.java:1)
at com.sun.jersey.core.impl.provider.xml.LazySingletonContextProvider.get(LazySingletonContextProvider.java:80)
at com.sun.jersey.core.impl.provider.xml.LazySingletonContextProvider.access$000(LazySingletonContextProvider.java:52)
at com.sun.jersey.core.impl.provider.xml.LazySingletonContextProvider$1.getValue(LazySingletonContextProvider.java:69)
at com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable$1.getValue(AbstractHttpContextInjectable.java:100)
at com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:43)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:119)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:166)
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:67)
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:259)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:83)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:133)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:71)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:990)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:941)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:932)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:384)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:451)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:632)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:538)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:478)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:517)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:225)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:937)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:406)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:871)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110)
at org.eclipse.jetty.server.Server.handle(Server.java:346)
at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:589)
at org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:1048)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:601)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:214)
at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:411)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:535)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:529)
at java.lang.Thread.run(Thread.java:662)
I have a jndi.properties file to configure my InitialContext (located in my resource folder src/main/resources)
java.naming.factory.url.pkgs=org.eclipse.jetty.jndi
java.naming.factory.initial=org.eclipse.jetty.jndi.InitialContextFactory
I also have a jetty-env.xml file in the webapp/WEB-INF folder:
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
<!--<Set name="ConfigurationClasses">
<Ref id="plusConfig"/>
</Set> -->
<!-- MySql datasource org.eclipse.jetty.plus.jndi.Resource Factory-->
<New id="DSTest" class="org.mortbay.jetty.plus.naming.Resource">
<Arg></Arg>
<Arg>jdbc/DSTest</Arg>
<Arg>
<New class="com.mchange.v2.c3p0.ComboPooledDataSource">
<Set name="driverClassName">com.mysql.jdbc.Driver</Set>
<Set name="url">jdbc:mysql://host/</Set>
<Set name="username">username</Set>
<Set name="password">password</Set>
<Set name="checkoutTimeout">5000</Set>
<Set name="initialPoolSize">10</Set>
<Set name="maxIdleTime">30</Set>
<Set name="maxPoolSize">160</Set>
<Set name="minPoolSize">10</Set>
<Set name="maxStatements">200</Set>
<Set name="maxConnectionAge">0</Set>
<Set name="acquireIncrement">15</Set>
</New>
</Arg>
</New>
</Configure>
And I added those lines in my web.xml file:
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/DSTest</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
I seem to have followed all the required steps, but I still get a javax.naming.NameNotFoundException when doing the lookup...
Any hints?
Thanks!
EDIT:
I forgot to put how I do my lookup.
InitialContext ctx = new InitialContext();
DataSource dataSource = (DataSource)ctx.lookup("java:comp/env/jdbc/DSTest");
Stupid question but this page http://docs.codehaus.org/display/JETTY/JNDI#JNDI-resref states that using JNDI with Jetty is an optional feature that needs to be enabled.
Specifically it says The class that does this is org.mortbay.jetty.plus.webapp.Configuration, and we specify its name in the list of configurations to be applied to the webapp when we define the org.mortbay.jetty.webapp.WebAppContext for it.

Categories