Jetty - set system property

27,942

Solution 1

To configure a web application it is better to avoid system properties and to use JNDI instead.

Recently I posted an example on how to accomplish that with Jetty.

Solution 2

For the record, if you really need to do this through system properties (I did) you can do this to append for example -Drun.mode=staging to the system properties:

<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>run.mode</Arg>
        <Arg>staging</Arg>
      </Call>
    </New>
  </Arg>
</Call>

... and yes you can probably can program your application through this ;-)

Solution 3

If you're starting Jetty through its Java API for a testing or 'embedded' application, the following example shows actually setting Java System properties prior to the startup of your WebAppContext.

    private void startJetty() {
    try {
        long startTime = System.currentTimeMillis();

        server = new Server();
        setUpSystemProperties(server);

        Connector connector = new SelectChannelConnector();
        connector.setPort(port);
        server.addConnector(connector);

        WebAppContext webAppContext = new WebAppContext();
        webAppContext.setWar("src/main/webapp");
        server.setHandler(webAppContext);

        server.start();
    }
    catch (Exception e) {
        throw new RuntimeException("Failed to set-up web server fixture", e);
    }
}

private void setUpSystemProperties(Server jettyServer) {
    final Properties systemProperties = new Properties();
    // set your system properties...
    systemProperties.setProperty("yourProperty", "yourValue");
    jettyServer.addLifeCycleListener(new SystemPropertiesLifeCycleListener(systemProperties));
}

private class SystemPropertiesLifeCycleListener extends AbstractLifeCycleListener {
    private Properties toSet;

    public SystemPropertiesLifeCycleListener(Properties toSet) {
        this.toSet = toSet;
    }

    @Override
    public void lifeCycleStarting(LifeCycle anyLifeCycle) {
        // add to (don't replace) System.getProperties()
        System.getProperties().putAll(toSet);
    }
}

Unlike most of these answers, I won't lecture you about whether this is 'proper' compared to JNDI or some other technology you didn't ask about.

Solution 4

I'm going to accept @vanje answer since it got me thinking into right direction. Here's what I ended up using:

  1. Create jetty-web.xml outside of your WAR distro (no you don't want to package it with WAR if you want to configure the app from "outside")
  2. Place jetty-web.xml alongside of jetty.xml
  3. I needed just a single parameter so I ended up with the following:

jetty-web.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"    
     "http://jetty.mortbay.org/configure.dtd">
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
    <New class="org.mortbay.jetty.plus.naming.EnvEntry">
        <Arg>myOwnParam</Arg>
        <Arg type="java.lang.String">//some/path/to/the/file</Arg>
    </New>
</Configure>

Java snippet

    InitialContext c = new InitialContext();
    EnvEntry env = (EnvEntry)
         c.lookup("org.mortbay.jetty.plus.naming.EnvEntry/myOwnParam");
    final String myString = (String) env.getObjectToBind();

The biggest gotcha for me here was that I was trying to get myString from the defaul env which didn't work until I realized that JNDI was using local context. This is OK for me but will break portability if you try to move WAR on say Tomcat. If someone can post an example how this can be saved into default context that would be greatOwnParam

Share:
27,942

Related videos on Youtube

Bostone
Author by

Bostone

Most of my past experience is in Enterprise Java and related technologies. I started working with Java in 1996, prior to that I did about 5 years of C/C++ My last 8 years are all contract jobs for large clients, all loosely related to Spring framework and other various Open Source frameworks. Since 2008 I've been closely involved with Android development, authoring and writing Jobrio (a.k.a. Hire-A-Droid) and Droidin. I'm also collaborating with good folks of Flud reader to deliver Android version of their popular app I also (occasionally) maintain my dev blog

Updated on July 09, 2022

Comments

  • Bostone
    Bostone almost 2 years

    I run webapp on Jetty. The configuration for the app come from file that lives on the same server where Jetty is running. Inside the app I rely on the system property to obtain path to the file so I can parse it. E.g.

    final String loc = System.getProperty(FACTORY);
    

    Now I can start jetty with D switch to provide $FACTORY on the command line but I rather put it in jetty.xml if I can. I know there is <SystemProperty /> tag but that seems to just provide system value that already exists for the <Set/> tag. Can someone give me example how this can be achieved? (If it can be achieved)

  • Bostone
    Bostone over 13 years
    Thanks but I still want to know if it can be done and how. Frankly if it set from jetty.xml and not in the system itself I don't see why it is bad
  • vanje
    vanje over 13 years
    The benefit is portability. If you ever will deploy your web app into another container then you can be sure, that there is a way to set JNDI paramaters. As far as I know the SystemProperty tag in jetty.xml is only for reading a system property. Here is the Jetty syntax reference: docs.codehaus.org/display/JETTY/…
  • vanje
    vanje over 13 years
    The only location I know to set a system property is either the configuration file for the Windows Jetty service or the appropriate Unix shell script.
  • Bostone
    Bostone over 13 years
    There's no question of portability if the parameter set in the config file in platform independend fashion (e.g. as XML tag). I'm not relying on system property to be set. But thank you for your suggestion.
  • Ted Pennings
    Ted Pennings over 13 years
    This is a perfect answer. The only thing I'd add is that the myOwnParam value can be anything and does not necessary need to be a path to a file. (At first glance I thought it had to be a path to a properties file.)
  • Mark Lilback
    Mark Lilback almost 13 years
    Thank you for this. I don't want to change the command line argument, but I need to set the file.encoding property via jetty.xml.
  • Ryan Shillington
    Ryan Shillington almost 12 years
    A hack, but a nice one, to be sure.
  • Michele Renda
    Michele Renda almost 12 years
    I add a bit more compact version: <Call class="java.lang.System" name="setProperty"> <Arg>run.mode</Arg> <Arg>staging</Arg> </Call>
  • user11153
    user11153 about 9 years
    If you enclose it in <Configure id="Server" class="org.eclipse.jetty.server.Server"> tag, you can ship it as standalone XML file - just add path to it in $JETTY_HOME/etc/jetty.conf