Java - application configuration


  • Discourse touched me in a no-no place

    So I have this Java program--a servlet, actually--that will be running on more than one machine. Each instance needs a single piece of information (a URL) that will be different on each machine. What's the simplest/most straightforward way of doing that? I thought asking here would be easier/faster than trawling SE or trying to figure it out myself.

    What's actually going to differ is which host the URL is called on: dev needs to call a dev machine, QA, a QA machine, and so on, although the list of machines isn't likely to ever change. I just don't want to have to put the URL (the hostname, actually) in the source.



  • Is this for a database connection, the url of the box you're running on, or an external URL?

    I ask because the three would probably each be handled differently.


  • Discourse touched me in a no-no place

    External URL the servlet will communicate with. Something similar in concept to an INI file is the gist of what I'm looking for--on servlet startup, obtain the hostname, so I can call a fixed URL on that hostname.


  • Banned

    I know nothing about Java, but I'd say a text file.


  • Discourse touched me in a no-no place

    That makes a certain amount of sense, but I was wondering if there was a specific API. the class java.util.Properties seems like it might be useful but I don't know if it will be the simplest/best thing to use (for example, if it creates a binary file, that means I have to write another program to initially create the file for each server, as opposed to just opening up a copy of Notepad.



  • java.util.Properties are just plain text key-value-pairs usually of the format:

    foo=bar



  • I know for a fact you can store things like URLs in the webapp's web.xml. However, some application servers won't let you modify that in the deployed application (or won't recognize the changes).

    Sooo.... it might be better to modify a Properties file instead.

    Properties files can be placed in the web app's WEB-INF/classes directory.

    In order to read files from a web application, you must use one of the getResourceAsStream methods.

    For instance, if I were trying to read myservet.properties from a class named MyServlet...

    InputStream in = MyServlet.class.getResourceAsStream("/myservlet.properties");
    Properties props = new Properties();
    props.load(in);
    in.close();
    

    Edit: Forgot to close the InputStream above. Fixed now.

    Incidentally, a properties file just looks like this:

    key=value
    anotherkey=anothervalue
    

    (I had to look in my app's log4j.properties file to get the syntax for the file's contents, you'd think Oracle would document it somewhere)



  • You can always set a environment variable and pass it as an argument when you start Tomcat(?)

    $ java -Denv=qa bla bla
    
    System.getProperty("env");
    

  • Discourse touched me in a no-no place

    @MathNerdCNU said:

    java.util.Properties are just plain text key-value-pairs

    Cool. I spent about 3 minutes looking at the javadoc and wasn't sure.

    @powerlord said:

    I know for a fact you can store things like URLs in the webapp's web.xml. However, some application servers won't let you modify that in the deployed application (or won't recognize the changes).

    We'll be running Tomcat 8.

    It sounds like Properties files will be the way for me to go, as I can just create a subdir in our source tree[1] for each server, and stick a properties file in each directory, with the proper data in each one, although the other way should work too. (How do you use web.inf? I'm still kind of new to the servlet world. I was planning on sharing a single web.inf along with all the different properties files, but if I can reduce that to "just one web.inf per machine and no properties files" that might be even better.)

    [1] Getting source control into this company is a lost cause.


  • Discourse touched me in a no-no place

    Hmm. This is Windows, and we're using the "start Tomcat as a service" so I assume you'd set a Windows environment variable instead, but that could possibly work too.

    I'm liking the idea of using a file a bit better as that will simplify installation/administration.



  • I think this will work for using the web.xml. Most of my Tomcat experience has been fighting against trying to get the remoteAddress valve thing to restrict access to only allow connections from localhost. Don't ask.



  • This post is deleted!


  • Just realized my last post had Context Params in web.xml with the code to fetch Init params. Whoops.

    What @MathNerdCNU said for init-params.

    Context Params are similar, but bound to the servlet context instead of a particular servlet.

    They look like this in web.xml:

    <context-param>
      <param-name>key</param-name>
      <param-value>value</param-value>
    </context-param>
    

    For an HttpServlet, you can fetch Context Params using

    String value = this.getServletContext().getInitParameter("key");
    

    Classes that just implement Servlet instead of GenericServlet or HttpServlet will need to do this:

    String value = this.getServletConfig().getServletContext().getInitParameter("key");

  • Discourse touched me in a no-no place

    Oh, that looks like it'll be perfect for my needs. Thanks.


  • Discourse touched me in a no-no place

    @powerlord said:

    Context Params are similar, but bound to the servlet context instead of a particular servlet.

    I don't really understand contexts yet. In this case, there will essentially only be one copy of the servlet on each server, so init-params will probably work fine for me.



  • If you're extending HttpServlet, you can call this.getInitParameter("key") and skip the getServletConfig()

    Yay convenience methods.


  • Discourse touched me in a no-no place

    @powerlord said:

    If you're extending HttpServlet

    I am. It seemed to make more sense than extending the base class.

    @powerlord said:

    Yay convenience methods.

    Indeed.



  • @FrostCat said:

    I am. It seemed to make more sense than extending the base class.

    @CodingHorrorBot, what am I doing if I implement Servlet instead of extending HttpServlet?


  • 🔀

    @powerlord Is Doing It Wrong™


Log in to reply