3
\$\begingroup\$

I am no newcomer to Java. One thing that confounds me is why it is so messy to load values from .properties files.

I have an application where, if the .properties file is found, then the value if found, should be used. And in any other circumstance, to use the default. (In the correct deployment, the server is run with sufficient permissions to engage with the socket listener 443, whereas in the development environment or any other environment where a person goes to the trouble to insert the .properties file, another port will be used).

The location of the file is com/foo/bar/webserver.properties in the in the same directory as the class file com/foo/bar/WebServer.class.

The content of webserver.properties is simply:

 listen=4444

Since this such a terribly simple function I would like to know if the community of reviewers sees a more elegant/succinct/secure/complete/correct way to load the value. I feel like I must be overlooking something basic for what feels like, to me, should be a one-liner more like the imaginary API:

    // set int value for key "listen", or else default value 443
    int port = Properties.loadProperties( "webserver.properties" ).getInt( "listen", 443 );

And here is my real code for review:

    int port;
    try ( InputStream webserverProperties = WebServer.class.getResourceAsStream( "webserver.properties" ) ) {
        if ( webserverProperties == null ) {
            port = 443;
        } else {
            Properties p = new Properties();
            p.load( webserverProperties );
            String listen = p.getProperty( "listen", "443" );
            port = Integer.parseInt( listen );
        }
    }
    catch ( NumberFormatException e ) { port = 443; }
    finally {}
\$\endgroup\$
8
  • \$\begingroup\$ Have you consider using xml de/serializing to load and save the properties? \$\endgroup\$
    – user33306
    Commented Nov 26, 2018 at 15:39
  • 2
    \$\begingroup\$ Java's Properties class is old, and it shows. It's also designed specifically to work only with String values. It sounds like it's not a great choice for the problem you've got. You might want to consider using a different abstraction or writing your own. It shouldn't be that hard to compose a Properties instance into the fluent API you're describing as your ideal. \$\endgroup\$
    – Eric Stein
    Commented Nov 26, 2018 at 16:02
  • \$\begingroup\$ @tinstaafl, no I did not, because I am reading a single int value. I fail to see how that would simplify the operation, but I am happy to learn something from your answer. \$\endgroup\$ Commented Nov 26, 2018 at 16:47
  • \$\begingroup\$ I realize your code only loads one property value. However your title indicates you may want to load more than one. It seems to in that case de/serializing would be more efficient. \$\endgroup\$
    – user33306
    Commented Nov 26, 2018 at 17:11
  • \$\begingroup\$ I think if I had many properties to read, I would write a Properties intermediary class with methods that would look very much like my code sample. And then, I think it would be appropriate. But, to only read a single int I think 12 lines of code is dubious. \$\endgroup\$ Commented Nov 26, 2018 at 17:18

1 Answer 1

1
\$\begingroup\$

you could at least get rid of the if by combining the exceptions:

int port;
try ( InputStream webserverProperties = WebServer.class.getResourceAsStream( "webserver.properties" ) ) {
        Properties p = new Properties();
        p.load( webserverProperties );
        String listen = p.getProperty( "listen", "443" );
        port = Integer.parseInt( listen );
}
catch ( NumberFormatException|NullPointerException e ) { port = 443; }
finally {}

or ignore exceptions at all:

int port= 443;
try ( InputStream webserverProperties = WebServer.class.getResourceAsStream( "webserver.properties" ) ) {
        Properties p = new Properties();
        p.load( webserverProperties );
        String listen = p.getProperty( "listen", "443" );
        port = Integer.parseInt( listen );
}
catch ( Exception e ) {}
finally {}
\$\endgroup\$
1
  • \$\begingroup\$ Yes, I think the second option is good, and in fact in this case the empty finally{} block can also be omitted. Thank you. \$\endgroup\$ Commented Nov 28, 2018 at 14:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.