1

I am working on an application created using the spring IO framework which displays the hostname using a json format.

The application is working fine when it is started from the command line by the command:

java -jar spring-cd.jar

which gives the required output:

enter image description here

but when it is run as a service using a systemd unit file the reuqired output(hostname) it is null:

enter image description here

the code for the unit file is the following:

[Unit]
After=network.target

[Service]
ExecStart=/usr/bin/java -jar /opt/training/spring-cd/spring-cd.jar
Type=simple
User=root
Restart=always

[Install]
WantedBy=default.target

I do not understand what is the difference between those approaches and why the second displays "null". Also i am fairly new and to systemd and linux.

Relevant Java code:

import java.lang.System;

public class Greeting {
    private final String content;

    public Greeting() {
        this.content = getHostname();
    }

    private String getHostname(){
        String hostname;
        if (System.getProperty("os.name").startsWith("Windows")) {
            hostname = System.getenv("COMPUTERNAME");
        } else {
            hostname = System.getenv("HOSTNAME");
        }
        return hostname;
    }

    public String getContent() {
        return content;
    }
}
randomir
  • 17,989
  • 1
  • 40
  • 55
MiM1
  • 59
  • 1
  • 7

1 Answers1

2

The environment variable HOSTNAME you use in your code is not available in the Java program's environment when run by systemd.

The simple fix is to add the missing environment variable directly in your service Unit file, under [Service] section:

[Service]
...
Environment=HOSTNAME=%H

The %H specifier stands for the hostname of the running system at the point in time the unit configuration is loaded.

Alternatively (instead of defining each variable with theEnvironment directive), you could put all variables in a file and use the EnvironmentFile directive, or pass a selection of variables with PassEnvironment directive.


However, a more portable way would be to use the standard Java class java.net.InetAddress and getHostName() method:

hostname = InetAddress.getLocalHost().getHostName();

(as explained in this answer)

randomir
  • 17,989
  • 1
  • 40
  • 55
  • You're welcome! I would suggest you also try the more portable approach, where Java takes care about finding out the proper hostname on both Windows and Linux. It could simplify the code and its maintenance. – randomir Sep 27 '17 at 14:32