Enable programmatic concurrency on Jetty with WorkManager - java

I managed to configure a custom implementation of the CommonJ − JSR 237 Timer & WorkManager API (http://commonj.myfoo.de) as a JNDI resource on Jetty 6 and 8, but it only works in a global scope.
With this solution JNDI name of the resource is wm/WorkManager, I need it to be java:comp/env/wm/WorkManager, but due to restrictions, I cannot use java:comp/env in a global JNDI name because it's reserved to application scoped resources.
I've created a new configuration file called {jetty.home}/etc/jetty-wtm.xml and added to {jetty.home}/start.ini.
Here is jetty-wtm.xmlcontent for Jetty 6, for greater versions it's a bit different, but works too:
<!-- =============================================================== -->
<!-- Configure Server Time and Work Managers -->
<!-- =============================================================== -->
<Configure id="Server" class="org.mortbay.jetty.Server">
<New id="WorkManager" class="org.mortbay.jetty.plus.naming.Resource">
<Arg>wm/WorkManager</Arg>
<Arg>
<New class="de.myfoo.commonj.work.FooWorkManager">
<Arg>
<New id="threadPool" class="de.myfoo.commonj.util.ThreadPool">
<Arg type="int">0</Arg>
<Arg type="int">10</Arg>
<Arg type="int">2</Arg>
</New>
</Arg>
</New>
</Arg>
</New>
<New id="TimeManager" class="org.mortbay.jetty.plus.naming.Resource">
<Arg>tm/TimeManager</Arg>
<Arg>
<New class="de.myfoo.commonj.timers.FooTimerManager">
<Arg>
<New id="threadPool" class="de.myfoo.commonj.util.ThreadPool">
<Arg type="int">0</Arg>
<Arg type="int">10</Arg>
<Arg type="int">2</Arg>
</New>
</Arg>
</New>
</Arg>
</New>
</Configure>
I need to mantain standard JNDI naming java:comp/env/{RESOURCE} specifically java:comp/env/wm/MyWorkManageracross servers, but standard WEB-INF\jetty-env.xml configuration file doesn't work.
Any ideas?
UPDATE:
I've tested the jetty-env.xml local configuration file in Jetty 9 and it works as expected. It seems in versions under 9 JNDI it's not fully supported. Here is the configuration file contents:
<Configure id="wac" class="org.eclipse.jetty.webapp.WebAppContext">
<New id="WorkManager" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg><Ref id="wac"/></Arg>
<Arg>wm/MyWorkManager</Arg>
<Arg>
<New class="de.myfoo.commonj.work.FooWorkManager">
<Arg>
<New id="threadPool" class="de.myfoo.commonj.util.ThreadPool">
<Arg type="int">0</Arg>
<Arg type="int">10</Arg>
<Arg type="int">2</Arg>
</New>
</Arg>
</New>
</Arg>
</New>
</Configure>

Did you check this,
Sometimes it is useful to pass configuration information to a web app at runtime that you either cannot or cannot conveniently code into
a web.xml . In such cases, you can use
org.eclipse.jetty.plus.jndi.EnvEntry, and even override an entry of
the same name in web.xml.
<New class="org.eclipse.jetty.plus.jndi.EnvEntry">
<Arg></Arg>
<Arg>mySpecialValue</Arg>
<Arg type="java.lang.Integer">4000</Arg>
<Arg type="boolean">true</Arg>
</New>
This example defines a virtual env-entry called mySpecialValue with
value 4000 that is unique within the whole JVM. It is put into JNDI at
java:comp/env/mySpecialValue for every web app deployed. Moreover,
the boolean argument indicates that this value overrides an env-entry
of the same name in web.xml. If you don't want to override, then omit
this argument, or set it to false.
For Resource in custom files inside etc, the documentation states that
Assume the following naming entry is in
$JETTY_HOME/etc/jetty-myjndi.xml:
<New id="jdbc/myds" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/myds</Arg>
<Arg>
<New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
<Set name="Url">jdbc:mysql://localhost:3306/chat</Set>
<Set name="User">root</Set>
<Set name="Password">sillyness</Set>
</New>
</Arg>
</New>
Then you can link jdbc/myds into your webapp's namespace as
java:comp/env/jdbc/myfoo by using a WEB-INF/jetty-env.xml file:
<Call class="org.eclipse.jetty.plus.jndi.NamingEntryUtil" name="bindToENC">
<Arg></Arg> <!-- scope of naming entry, ie same as first argument to your naming entry definition, in this case, null -->
<Arg>jdbc/myfoo</Arg>
<Arg>jdbc/myds</Arg>
</Call>
Note that you must use a WEB-INF/jetty-env.xml file to call the
"bindToENC" method and not a context xml file, as the latter is not
interpreted at the correct phase of the webapp's deployment to have
the java:comp/env namespace created.

Related

Setting up a dedicated Executor per ServerConnector in Jetty

I'm trying to configure a dedicated executor in jetty.xml (jetty-9) for each of my ServerConnectors, as I'm able to do in Tomcat, but for some reason I get lost.
I'm using the following configuration:
<Call name="addConnector">
<Arg>
<New id="proxyConnector" class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server"><Ref refid="Server" /></Arg>
<Arg name="acceptors" type="int">-1</Arg>
<Arg name="selectors" type="int">-1</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>
<Arg name="compliance"><Call class="org.eclipse.jetty.http.HttpCompliance" name="valueOf"><Arg><Property name="jetty.http.compliance" default="RFC7230"/></Arg></Call></Arg>
</New>
</Item>
</Array>
</Arg>
<Set name="host">127.0.0.1</Set>
<Set name="port">50000</Set>
<Set name="idleTimeout">30000</Set>
<Set name="soLingerTime">-1</Set>
<Set name="acceptorPriorityDelta">0</Set>
<Set name="acceptQueueSize">0</Set>
</New>
</Arg>
</Call>
Is this even possible ?
Executors are server-wide, and many components within Jetty expect that.
If you feel you need this, file an enhancement request at
https://github.com/eclipse/jetty.project/issues

Using Blazegraph's `NanoSparqlServer`, how to clear the graph between tests?

I am using Blazegraph's 1.5.3 version of their Bigdata DB (now rebranded as Blazegraph). I have a service that acts as a Gateway, implementing a bunch of persistence-layer methods. Now I'm writing unit tests for those methods. I'm using the embedded setup with Jetty. My setup code is below:
int port = 0; // random port
String namespace = "kb";
int queryThreadPoolSize = ConfigParams.DEFAULT_QUERY_THREAD_POOL_SIZE;
boolean forceOverflow = false;
String servletContextListenerClass = ConfigParams.DEFAULT_SERVLET_CONTEXT_LISTENER_CLASS;
System.setProperty(SystemProperties.JETTY_XML, "jetty.xml");
String propertyFile = "RWStore.properties";
System.setProperty(SystemProperties.BIGDATA_PROPERTY_FILE, propertyFile);
final Map<String, String> initParams = new LinkedHashMap<>();
initParams.put("propertyFile", propertyFile);
initParams.put("namespace", namespace);
initParams.put("queryThreadPoolSize", Integer.toString(queryThreadPoolSize));
initParams.put("forceOverflow", Boolean.toString(forceOverflow));
initParams.put("servletContextListenerClass", servletContextListenerClass);
sparqlServer = NanoSparqlServer.newInstance(port, journal, initParams);
LOGGER.info("Waiting for NanoSparqlServer to start...");
NanoSparqlServer.awaitServerStart(sparqlServer);
serverUrl = sparqlServer.getURI().toString();
LOGGER.info("NanoSparqlServer started on: " + serverUrl + '\n');
I am using the default jetty.xml configuration from the com.bigdata 1.5.3 jar:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<!-- See http://www.eclipse.org/jetty/documentation/current/ -->
<!-- See http://wiki.eclipse.org/Jetty/Reference/jetty.xml_syntax -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Configure the Server Thread Pool. -->
<!-- The server holds a common thread pool which is used by -->
<!-- default as the executor used by all connectors and servlet -->
<!-- dispatches. -->
<!-- -->
<!-- Configuring a fixed thread pool is vital to controlling the -->
<!-- maximal memory footprint of the server and is a key tuning -->
<!-- parameter for tuning. In an application that rarely blocks -->
<!-- then maximal threads may be close to the number of 5*CPUs. -->
<!-- In an application that frequently blocks, then maximal -->
<!-- threads should be set as high as possible given the memory -->
<!-- available. -->
<!-- -->
<!-- Consult the javadoc of o.e.j.util.thread.QueuedThreadPool -->
<!-- for all configuration that may be set here. -->
<!-- =========================================================== -->
<Arg name="threadpool"><New id="threadpool" class="org.eclipse.jetty.util.thread.QueuedThreadPool"/></Arg>
<Get name="ThreadPool">
<Set name="minThreads" type="int"><Property name="jetty.threads.min" default="10"/></Set>
<Set name="maxThreads" type="int"><Property name="jetty.threads.max" default="64"/></Set>
<Set name="idleTimeout" type="int"><Property name="jetty.threads.timeout" default="60000"/></Set>
<Set name="detailedDump">false</Set>
</Get>
<!-- =========================================================== -->
<!-- Get the platform mbean server -->
<!-- =========================================================== -->
<Call id="MBeanServer" class="java.lang.management.ManagementFactory"
name="getPlatformMBeanServer" />
<!-- =========================================================== -->
<!-- Initialize the Jetty MBean container -->
<!-- =========================================================== -->
<!-- Note: This breaks CI if it is enabled
<Call name="addBean">
<Arg>
<New id="MBeanContainer" class="org.eclipse.jetty.jmx.MBeanContainer">
<Arg>
<Ref refid="MBeanServer" />
</Arg>
</New>
</Arg>
</Call>-->
<!-- Add the static log to the MBean server.
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.util.log.Log" />
</Arg>
</Call>-->
<!-- For remote MBean access (optional)
<New id="ConnectorServer" class="org.eclipse.jetty.jmx.ConnectorServer">
<Arg>
<New class="javax.management.remote.JMXServiceURL">
<Arg type="java.lang.String">rmi</Arg>
<Arg type="java.lang.String" />
<Arg type="java.lang.Integer"><SystemProperty name="jetty.jmxrmiport" default="1090"/></Arg>
<Arg type="java.lang.String">/jndi/rmi://<SystemProperty name="jetty.jmxrmihost" default="localhost"/>:<SystemProperty name="jetty.jmxrmiport" default="1099"/>/jmxrmi</Arg>
</New>
</Arg>
<Arg>org.eclipse.jetty.jmx:name=rmiconnectorserver</Arg>
<Call name="start" />
</New>-->
<!-- =========================================================== -->
<!-- Http Configuration. -->
<!-- This is a common configuration instance used by all -->
<!-- connectors that can carry HTTP semantics (HTTP, HTTPS, SPDY)-->
<!-- It configures the non wire protocol aspects of the HTTP -->
<!-- semantic. -->
<!-- -->
<!-- Consult the javadoc of o.e.j.server.HttpConfiguration -->
<!-- for all configuration that may be set here. -->
<!-- =========================================================== -->
<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>
<!-- Uncomment to enable handling of X-Forwarded- style headers
<Call name="addCustomizer">
<Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
</Call>
-->
</New>
<!-- Configure the HTTP endpoint. -->
<Call name="addConnector">
<Arg>
<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"><SystemProperty name="jetty.host" /></Set>
<Set name="port"><SystemProperty name="jetty.port" default="9999" /></Set>
<Set name="idleTimeout"><SystemProperty name="http.timeout" default="30000"/></Set>
</New>
</Arg>
</Call>
<!-- =========================================================== -->
<!-- Set handler Collection Structure -->
<!-- =========================================================== -->
<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">
<Call name="addHandler">
<Arg>
<!-- This is the redirect from root to /bigdata -->
<New id="moved" class="org.eclipse.jetty.server.handler.MovedContextHandler">
<Set name="contextPath">/</Set>
<Set name="newContextURL">/bigdata</Set>
<Set name="permanent">true</Set>
<Set name="discardPathInfo">false</Set>
<Set name="discardQuery">false</Set>
</New>
</Arg>
</Call>
<Call name="addHandler">
<Arg>
<!-- This is the bigdata web application. -->
<New id="WebAppContext" class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="war"><SystemProperty name="jetty.resourceBase" default="bigdata-war/src"/></Set>
<Set name="contextPath">/bigdata</Set>
<Set name="descriptor">WEB-INF/web.xml</Set>
<Set name="parentLoaderPriority">true</Set>
<Set name="extractWAR">false</Set>
<Set name="overrideDescriptor"><SystemProperty name="jetty.overrideWebXml" default="bigdata-war/src/WEB-INF/override-web.xml"/></Set>
<Set name="maxFormContentSize">10485760</Set>
</New>
</Arg>
</Call>
</New>
</Item>
</Array>
</Set>
</New>
</Set>
<!-- =========================================================== -->
<!-- extra server options -->
<!-- =========================================================== -->
<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>
... and I am using the default RWStore.properties from the same jar:
#
# Note: These options are applied when the journal and the triple store are
# first created.
##
## Journal options.
##
# The backing file. This contains all your data. You want to put this someplace
# safe. The default locator will wind up in the directory from which you start
# your servlet container.
com.bigdata.journal.AbstractJournal.createTempFile=true
# The persistence engine. Use 'Disk' for the WORM or 'DiskRW' for the RWStore.
com.bigdata.journal.AbstractJournal.bufferMode=DiskRW
# Setup for the RWStore recycler rather than session protection.
com.bigdata.service.AbstractTransactionService.minReleaseAge=1
# Enable group commit. See http://wiki.blazegraph.com/wiki/index.php/GroupCommit and BLZG-192.
#com.bigdata.journal.Journal.groupCommit=false
com.bigdata.btree.writeRetentionQueue.capacity=4000
com.bigdata.btree.BTree.branchingFactor=128
# 200M initial extent.
com.bigdata.journal.AbstractJournal.initialExtent=209715200
com.bigdata.journal.AbstractJournal.maximumExtent=209715200
##
## Setup for QUADS mode without the full text index.
##
com.bigdata.rdf.sail.truthMaintenance=false
com.bigdata.rdf.store.AbstractTripleStore.quads=true
com.bigdata.rdf.store.AbstractTripleStore.statementIdentifiers=false
com.bigdata.rdf.store.AbstractTripleStore.textIndex=false
com.bigdata.rdf.store.AbstractTripleStore.axiomsClass=com.bigdata.rdf.axioms.NoAxioms
# Bump up the branching factor for the lexicon indices on the default kb.
com.bigdata.namespace.kb.lex.com.bigdata.btree.BTree.branchingFactor=400
# Bump up the branching factor for the statement indices on the default kb.
com.bigdata.namespace.kb.spo.com.bigdata.btree.BTree.branchingFactor=1024
# Uncomment to enable collection of OS level performance counters. When
# collected they will be self-reported through the /counters servlet and
# the workbench "Performance" tab.
#
# com.bigdata.journal.Journal.collectPlatformStatistics=true
Using these configurations, the server starts up fine, and I can access the Web console, make queries, and interact via the BigdataGraphClient API in Java. Now I'm just trying to figure out how to clear out the graph to avoid data leakage between unit tests. I've tried the following:
Use the BigdataGraphClient Java API to remove all edges and vertices. Leaves some of these edges and vertices in place, for reasons unknown to me.
graph.getEdges.forEach(Edge::remove)
graph.getVertices.forEach(Vertex::remove)
Stop and destroy server. Leaves the journal file in place.
sparqlServer.stop(); sparqlServer.destroy();
Use a temporary journal file by setting com.bigdata.journal.AbstractJournal.createTempFile=true and commenting out com.bigdata.journal.AbstractJournal.file=bigdata.jnl. This clears the journal file, but it throws a DatasetNotFoundException after the first test.
Put the journal file in a temporary directory in /tmp/bigdata-test/bigdata.jnl and delete/recreate that directory between tests. This has the same problem as #2.
Tried to create my own Journal object and pass that in as the IndexManager parameter of the NanoSparqlServer.newInstance method. This fails due to a known issue with old Lucene dependencies. I cannot include these in my project because I am relying on the newer version of Lucene that conflicts with this one. The error thrown is the same as documented in the referenced Jira ticket.
Anybody know of a clean, reliable way to clear the graph between tests (in a tearDown method run after every test)?
Turns out I was running into another issue that made me think my first approach wasn't working. That approach works just fine. I'm leaving the question up in case someone else is wondering how to do this. I'm also open to cleaner/faster ways. If the tests insert a lot of data, iterating through all of the triples/quads and deleting them one-by-one can be slow. I'd prefer something like unlinking the files in the Journal.

Jetty session clustering using jetty-maven-plugin

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.

Passing system properties to Jetty runner through command line

I've a web application that runs with jetty. I include a client.jar in this web application for a functionality. client.jar needs a system property -Dconfig with location to the properties file. How do I pass this to when I start my application using jetty-runner ? I could only find setting it through jetty.xml but I'm trying to find if there is a way through command line.
This is not a solution to pass property through command line. I fixed this by passing below file jetty.xml to command line as below. I'm posting it here as it may help someone.
nohup $JAVA_HOME/bin/java -Denv=$1 -jar $LIB_PATH/jetty-runner-*.jar --config $CONF_PATH/jetty.xml $DIST_PATH/my-app*.war &
jetty.xml
<?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">
<Call class="java.lang.System" name="setProperties">
<Arg>
<New class="java.util.Properties">
<Call name="putAll">
<Arg>
<Call class="java.lang.System" name="getProperties" />
</Arg>
</Call>
<Call name="setProperty">
<Arg>iamconfig</Arg>
<Arg>iamclient.properties</Arg>
</Call>
</New>
</Arg>
</Call>
</Configure>
In our project, we have used below set of code to set system property while doing jetty:run
clean compile -Dcurrent.region=AIR jetty:run

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