Jetty session clustering using jetty-maven-plugin - java

I'm trying to set up session clustering using this
My jetty.xml:
....
<Set name="sessionIdManager">
<New id="jdbcIdMgr" class="org.eclipse.jetty.server.session.JDBCSessionIdManager">
<Arg>
<Ref id="Server"/>
</Arg>
<Set name="workerName"><Property name="jetty.jdbcSession.workerName" default="node1"/></Set>
<Set name="scavengeInterval"><Property name="jetty.jdbcSession.scavenge" default="1800"/></Set>
<Call name="setDriverInfo">
<Arg><Property name="jetty.jdbcSession.driverClass"
default="com.mysql.jdbc.jdbc2.optional.MysqlDataSource"/></Arg>
<Arg><Property name="jetty.jdbcSession.connectionURL"
default="jdbc:mysql://${datasource.dbServerName}:${datasource.dbServerPort}/${datasource.dbName}"/></Arg>
</Call>
</New>
</Set>
.....
My jetty-web.xml :
<Get name="Server">
<Get id="jdbcIdMgr" name="sessionIdManager"/>
</Get>
<Set name="sessionHandler">
<New class="org.eclipse.jetty.server.session.SessionHandler">
<Arg>
<New id="jdbcmgr" class="org.eclipse.jetty.server.session.JDBCSessionManager">
<Set name="idManager">
<Ref id="jdbcIdMgr"/>
</Set>
</New>
</Arg>
</New>
</Set>
The problem is that I'm getting NPE during server startup, because Server instance is not set to my WebAppContext instance so I can't get my sessionIdManager using :
<Get name="Server">
<Get id="jdbcIdMgr" name="sessionIdManager"/>
</Get>
I looked at jetty-maven plugin sources and found that at first it configures my WebAppContext instance and then in calls setServer:
//set up the webapp and any context provided
this.server.configureHandlers();
configureWebApplication();
this.server.addWebApplication(webApp);
How can I properly set up my session clustering stuff?

After digging in the sources I extended JDBCSessionManager class, where I set _sessionIdManager property:
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.session.HashSessionIdManager;
import org.eclipse.jetty.server.session.JDBCSessionManager;
public class ScoopSessionManager extends JDBCSessionManager {
#Override
public void doStart() throws Exception {
final Server server = getSessionHandler().getServer();
_sessionIdManager = server.getSessionIdManager();
if (_sessionIdManager == null) {
_sessionIdManager = new HashSessionIdManager();
server.setSessionIdManager(_sessionIdManager);
}
super.doStart();
}
}
Seems to be working now.

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>

JNDI Datasource Lookup / Close Issue on Jetty

I have a Spring Hibernate webapp with HikariCP running on Jetty with the following context file located in the base webapps folder:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id='testServer' class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/myServer</Set>
<Set name="war">C:\mypath\myServer.war</Set>
<New id="testDataSource" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg><Ref refid="testServer"/></Arg>
<Arg>jdbc/myDB</Arg>
<Arg>
<New class="com.zaxxer.hikari.HikariDataSource">
<Arg>
<New class="com.zaxxer.hikari.HikariConfig">
<Set name="connectionTestQuery">SELECT 1</Set>
<Set name="dataSourceClassName">com.mysql.jdbc.jdbc2.optional.MysqlDataSource</Set>
<Set name="maximumPoolSize">20</Set>
<Set name="connectionTimeout">30000</Set>
<Set name="username">user</Set>
<Set name="password">password</Set>
<Call name="addDataSourceProperty">
<Arg>url</Arg>
<Arg>jdbc:mysql://localhost/mydb?zeroDateTimeBehavior=convertToNull</Arg>
</Call>
<Call name="addDataSourceProperty">
<Arg>user</Arg>
<Arg>user</Arg>
</Call>
<Call name="addDataSourceProperty">
<Arg>password</Arg>
<Arg>password</Arg>
</Call>
<Call name="addDataSourceProperty">
<Arg>cachePrepStmts</Arg>
<Arg>true</Arg>
</Call>
<Call name="addDataSourceProperty">
<Arg>prepStmtCacheSize</Arg>
<Arg>250</Arg>
</Call>
<Call name="addDataSourceProperty">
<Arg>prepStmtCacheSqlLimit</Arg>
<Arg>2048</Arg>
</Call>
<Call name="addDataSourceProperty">
<Arg>useServerPrepStmts</Arg>
<Arg>true</Arg>
</Call>
</New>
</Arg>
</New>
</Arg>
</New>
</Configure>
In my applicationContext.xml file I am able to successfully lookup and use the datasource using the following:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/myDB"/>
The problem I am having is that when I hot deploy a new war file, the HikariCP datasource connection pool is left open, and the connections to the database remain.
I am trying to lookup and close the datasource in the contextDestroyed() method of a ServletContextListener using something like the following code:
try
{
initContext = new InitialContext();
envContext = (Context) initContext.lookup("java:comp/env");
ds = (DataSource) envContext.lookup("jdbc/myDB");
if (ds.getConnection() == null)
{
throw new RuntimeException("Failed to find the JNDI Datasource");
}
logger.info("JNDI HikariDataSource : " + System.identityHashCode(ds.getClass()));
logger.info("Local HikariDataSource: " + System.identityHashCode(HikariDataSource.class));
HikariDataSource hds = (HikariDataSource) ds;
hds.close();
} catch (Exception ex)
{
logger.log(Level.SEVERE, null, ex);
}
However I am getting the following exception when trying to cast the DataSource to a HikariDataSource:
java.lang.ClassCastException: com.zaxxer.hikari.HikariDataSource cannot be cast to com.zaxxer.hikari.HikariDataSource
I am also getting different identityHashCodes above which leads me to believe that I have 2 classloaders that have loaded separate instances of the HikariDataSource class. We would like the datasource to be specific to the webapp's context and to close it on hot deployment. What do I need to change to make this happen?

Java Based Spring WebApp not Running Jetty9

I have a war project with Java Based Spring Configuration (without web.xml) that runs perfectly on mvn jetty:run but when I put inside the machines with Jetty 9 the project is not running.
The jetty 9 server runs but the application doesn`t initialize at all.
The application consists in a Queue Subscriber.
It seems like I need to have a web.xml file.
Does anyone have an ideia what I`m missing?
The xml configuration file for the App on Jetty 9 server is (edit: with the correct conf file)
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<!--
JETTY_HOME="<%=node['api']['worker']['jetty']['jetty_home']%>"
JAVA_HOME="<%=node['api']['worker']['jetty']['java_home']%>"
JETTY_CONSOLE="<%=node['api']['worker']['jetty']['jetty_console']%>"
JETTY_USER="<%=node['api']['worker']['jetty']['jetty_user']%>"
JETTY_ARGS="<%=node['api']['worker']['jetty']['jetty_args']%>"
JETTY_RUN="<%=node['api']['worker']['jetty']['jetty_run']%>"
JAVA_OPTIONS="<%=node['api']['worker']['jetty']['java_options']%>"
-->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Get name="ThreadPool">
<Set name="minThreads" type="int"><Property name="threads.min" default="10"/></Set>
<Set name="maxThreads" type="int"><Property name="threads.max" default="200"/></Set>
<Set name="idleTimeout" type="int"><Property name="threads.timeout" default="60000"/></Set>
<Set name="detailedDump">false</Set>
</Get>
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.util.thread.ScheduledExecutorScheduler"/>
</Arg>
</Call>
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Set name="secureScheme">https</Set>
<Set name="securePort"><Property name="jetty.secure.port" default="8443" /></Set>
<Set name="outputBufferSize"><Property name="jetty.output.buffer.size" default="32768" /></Set>
<Set name="requestHeaderSize"><Property name="jetty.request.header.size" default="8192" /></Set>
<Set name="responseHeaderSize"><Property name="jetty.response.header.size" default="8192" /></Set>
<Set name="sendServerVersion"><Property name="jetty.send.server.version" default="true" /></Set>
<Set name="sendDateHeader"><Property name="jetty.send.date.header" default="false" /></Set>
<Set name="headerCacheSize">512</Set>
</New>
<New class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server"><Ref refid="Server" /></Arg>
<Arg name="factories">
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<Item>
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg name="config"><Ref refid="httpConfig" /></Arg>
</New>
</Item>
</Array>
</Arg>
<Set name="host"><Property name="jetty.host" /></Set>
<Set name="port"><Property name="jetty.port" default="8080"/></Set>
<Set name="idleTimeout"><Property name="http.timeout" default="30000"/></Set>
<Set name="soLingerTime"><Property name="http.soLingerTime" default="-1"/></Set>
<Set name="acceptQueueSize"><Property name="http.acceptQueueSize" default="0"/></Set>
</New>
<Call class="java.lang.System" name="setProperty">
<Arg>logback.configurationFile</Arg>
<Arg>file:///conf/worker/logback.xml</Arg>
</Call>
<Call class="java.lang.System" name="setProperty" >
<Arg>service.config.path</Arg>
<Arg>/opt/webapps/worker</Arg>
</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="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Item>
<Item>
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler">
<Set name="showContexts">false</Set>
</New>
</Item>
</Array>
</Set>
</New>
</Set>
<New class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/</Set>
<Set name="war"><Property name="jetty.webapps" default="." />/opt/webapps/worker.war</Set>
<Set name="extractWAR">true</Set>
</New>
<Call name="addBean">
<Arg>
<New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
<Set name="contexts">
<Ref refid="Contexts" />
</Set>
<Call id="webappprovider" name="addAppProvider">
<Arg>
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
<Set name="monitoredDirName"><Property name="jetty.home" default="." />/webapps</Set>
<Set name="scanInterval">1</Set>
<Set name="extractWars">true</Set>
<Set name="configurationClasses">
<Array type="java.lang.String">
<Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
<Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
<Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
<Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
<Item>org.eclipse.jetty.annotations.AnnotationConfiguration</Item>
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
</Array>
</Set>
</New>
</Arg>
</Call>
</New>
</Arg>
</Call>
<Set name="stopAtShutdown">true</Set>
<Set name="stopTimeout">5000</Set>
<Set name="dumpAfterStart"><Property name="jetty.dump.start" default="false"/></Set>
<Set name="dumpBeforeStop"><Property name="jetty.dump.stop" default="false"/></Set>
</Configure>
The jetty-console log is
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=128m; support was removed in 8.0
WARNING: System properties and/or JVM args set. Consider using --dry-run or --exec
2014-12-19 19:32:49.749:INFO:oejs.Server:main: jetty-9.0.3.v20130506
2014-12-19 19:32:49.800:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/opt/jetty- distribution-9.0.3.v20130506/webapps/] at interval 1
2014-12-19 19:32:51.554:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext#45afc369{/,file:/tmp/jetty-0.0.0.0-8080-worker.war-_-any-/webapp/,AVAILABLE}{/worker/worker.war}
2014-12-19 19:32:51.560:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/opt/jetty-distribution-9.0.3.v20130506/webapps/] at interval 1
2014-12-19 19:32:51.587:INFO:oejs.ServerConnector:main: Started ServerConnector#34cd072c{HTTP/1.1}{0.0.0.0:8080}
Edit: The xml configuration file is now correct and I had to uncomment the above options at ${jetty.home}/start.ini
# ===========================================================
# Enable additional webapp environment configurators
# -----------------------------------------------------------
OPTIONS=plus
etc/jetty-plus.xml
# ===========================================================
# Enable servlet 3.1 annotations
# -----------------------------------------------------------
OPTIONS=annotations
etc/jetty-annotations.xml
Some obvious things to fix first.
You are using Java 8, upgrade to Jetty 9.2.6 (Jetty 9.0.3 is too old and does not support Java 8 well)
Your DTD reference is bad, it is the one from Jetty 7, it has been known to cause problems in Jetty 9.
Use <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd"> instead.
Your class reference is bad, and should be fixed. "org.eclipse.jetty_runˆy.server.Server" doesn't exist

How to disable the SSLv3 protocol in Jetty to prevent Poodle Attack

Is there any specific exclusion list available which disables only SSLv3 ciphers are not TLSv1/2.
I have jetty 8, and upgrading to 9 is not an option now. My current jetty-ssl.xml looks as follows
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<Arg>
<New class="org.eclipse.jetty.http.ssl.SslContextFactory">
.........
</New>
</Arg>
<Set name="ExcludeCipherSuites">
<Array type="java.lang.String">
<Item>SSL_RSA_WITH_NULL_MD5</Item>
<Item>SSL_RSA_WITH_NULL_SHA</Item>
<Item>SSL_RSA_EXPORT_WITH_RC4_40_MD5</Item>
<Item>SSL_RSA_WITH_RC4_128_MD5</Item>
<Item>SSL_RSA_WITH_RC4_128_SHA</Item>
<Item>SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5</Item>
<Item>SSL_RSA_WITH_IDEA_CBC_SHA</Item>
<Item>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
<Item>SSL_RSA_WITH_DES_CBC_SHA</Item>
<Item>SSL_RSA_WITH_3DES_EDE_CBC_SHA</Item>
<Item>SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA</Item>
<Item>SSL_DH_DSS_WITH_DES_CBC_SHA</Item>
<Item>SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA</Item>
<Item>SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
<Item>SSL_DH_RSA_WITH_DES_CBC_SHA</Item>
<Item>SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA</Item>
<Item>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</Item>
<Item>SSL_DHE_DSS_WITH_DES_CBC_SHA</Item>
<Item>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</Item>
<Item>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
<Item>SSL_DHE_RSA_WITH_DES_CBC_SHA</Item>
<Item>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</Item>
<Item>SSL_DH_anon_EXPORT_WITH_RC4_40_MD5</Item>
<Item>SSL_DH_anon_WITH_RC4_128_MD5</Item>
<Item>SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA</Item>
<Item>SSL_DH_anon_WITH_DES_CBC_SHA</Item>
<Item>SSL_DH_anon_WITH_3DES_EDE_CBC_SHA</Item>
<Item>SSL_FORTEZZA_KEA_WITH_NULL_SHA</Item>
<Item>SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA</Item>
<Item>SSL_FORTEZZA_KEA_WITH_RC4_128_SHA</Item>
<Item>SSL_DHE_RSA_WITH_AES_128_CBC_SHA</Item>
<Item>SSL_RSA_WITH_AES_128_CBC_SHA</Item>
</Array>
</Set>
</New>
</Arg>
</Call>
still when i run "sslscan --no-failed --ssl3 localhost:443" i get
Supported Server Cipher(s):
Accepted SSLv3 128 bits DHE-RSA-AES128-SHA
Accepted SSLv3 128 bits AES128-SHA
Prefered Server Cipher(s):
SSLv3 128 bits DHE-RSA-AES128-SHA
I had to disable SSLv3 in an application where we integrate Jetty source code. Based on what I changed in code, I would guess you add the following:
<Set name="ExcludeProtocols">
<Array type="java.lang.String">
<Item>SSLv3</Item>
</Array>
</Set>
Give it a shot and let me know if it works for you.
To expand on #Lars answer ..
For Jetty 7, Jetty 8, and Jetty 9 you have to exclude the protocol SSLv3 (not the cipher) on any SslContextFactory you are using to configure for an SSL based Connector.
For a Jetty Distribution
Edit the ${jetty.home}/etc/jetty-ssl.xml and add the following XML snippet.
<Set name="ExcludeProtocols">
<Array type="java.lang.String">
<Item>SSLv3</Item>
</Array>
</Set>
Inside of any element that manages a org.eclipse.jetty.http.ssl.SslContextFactory
For Jetty Embedded
Any SslContextFactory you create/manage for your SSL based Connectors you just need to set the excluded protocols.
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.addExcludeProtocols("SSLv3");
sslContextFactory.setKeyStorePath(...);
...
I have configurated Jetty 8.1 whitout ssl3. You can see the complete structure of jetty-ssl.xml.
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<Arg>
<New class="org.eclipse.jetty.http.ssl.SslContextFactory">
<Set name="keyStore">... </Set>
<Set name="keyStorePassword">... </Set>
<Set name="keyManagerPassword">... </Set>
<Set name="trustStore">... </Set>
<Set name="trustStorePassword>... </Set
<Set name="ExcludeProtocols">
<Array type="java.lang.String">
<Item>SSLv3 </Item>
</Array>
</Set>
</New>
</Arg>
<Set name="port">... </Set>
<Set name="maxIdleTime">... </Set>
</New>
</Arg>
</Call>
</Configure>

Jetty, JNDI, Postgresql: Class not found

I'm trying to set up a JNDI DataSource in Jetty. In the start.ini file I have add the jetty-plus.xml file and the Options look like this:
OPTIONS=Server,resources,websocket,ext,plus,annotations
Then I'm adding the resource in my context file:
<New id="Traildevils" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg/>
<Arg>jdbc/Traildevils</Arg>
<Arg>
<New class="org.postgresql.ds.PGConnectionPoolDataSource">
<Set name="User">recom</Set>
<Set name="Password">recom</Set>
<Set name="DatabaseName">Traildevils</Set>
<Set name="ServerName">localhost</Set>
<Set name="PortNumber">5432</Set>
</New>
</Arg>
</New>
The postgresql-9.1-901.jdbc4.jar file is in the WEB-INF/lib of my war file.
When I'm now trying to start the jetty I get the following error:
2012-04-12 12:58:09.723:WARN:oejx.XmlConfiguration:Config error at
<New id="Traildevils" class="org.eclipse.jetty.plus.jndi.Resource"><Arg/>
<Arg>jdbc/Traildevils</Arg>
<Arg>|???<New class="org.postgresql.ds.PGConnectionPoolDataSource">
<Set name="User">recom</Set>
<Set name="Password">recom</Set>
<Set name="DatabaseName">Traildevils</Set>
<Set name="ServerName">localhost</Set><Set name="PortNumber">5432</Set></New>|??</Arg></New>
java.lang.ClassNotFoundException: org.postgresql.ds.PGConnectionPoolDataSource
What did I miss?
You need to add postgresql-9.1-901.jdbc4.jar to $JETTY_HOME/lib/ext.
This is because jetty initializes the JNDI context before it loads the classes from your WAR.

Categories