I don't think the following should drive this decision, but is just an FYI for anyone interested.
C is cleaner from a server-side design POV.
This URL String ultimately comes from org.jnp.server.Main, which exposes
public List getBootstrapURLs()
public String getBootstrapURL()
(The latter works by picking the first element in the list returned by the former, which is clunky.)
It's appropriate this info comes from Main, as it understands what the URL format is.
A separate class NamingServiceURLWriter actually writes the file. It (IMHO correctly) knows nothing about the URL format; it just gets a String and knows how to write it to the file.
To do a) or b) above, the logic to pick a) or b) from the overall list is either going to have to go in Main, which is a mixing of concerns, or in NamingServiceURLWriter, which forces that class to understand how to parse the URLs. Using c) avoids this kind of problem.
Again, not a huge issue.
We definitely don't want a), since connecting to the loopback address is probably going to provide a faster connection than an external address (though I guess that depends on how the OS does things).
As Charles said, b) works for us for the Jopr Agent's use case, but if you think c) is a better solution for other potential use cases (e.g. a remote client reading the jnp-service.url file via NFS and needing a non-loopback address), then we can work with that too. If you do c), the Jopr Agent would basically have to do the same logic you would have done to derive b) from c).