javajettyjndiworkmanagerscommonj

Enable programmatic concurrency on Jetty with WorkManager


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>

Solution

  • 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.