1

I have a java web application, which runs on a number of servers. Some of the servlets in this application load on startup to preload some data. The protocal for loading this data will change based on what server the application is deployed on. (The path of the files to be loaded change, also there are difference in security so getting some files is more involved then others). Is there a way that I can uniquely identify the server/machine that my application is on in the init function of a java servlet? I orginally was working with HttpServletRequest.getServerName(), which was enough, but it is not available in the init. I know about lazy initialization, so don't tell me to do that, I am trying to avoid that if possible since the load times on these file are significant. If I could find the machine name that would be perfect but i can't figure out how to get this out of the api's. All I need is a way to uniquely identify machines from the init.

Thanks for any help.

gbtimmon
  • 4,238
  • 1
  • 21
  • 36
  • Is the real requirement based on server name, or more based on server role, which you're determining by mapping names to roles implicitly? For instance, do you need your Test servers to handle things differently from your Production servers? – dbreaux Jul 31 '12 at 15:57
  • Server name, the problem is that the filesystems across our servers have different structures becuase of legacy issues. Server A B and C all need to access the same general set of file, but the prod copy is in a different location then the qa server or the dev server. Also prod has security which test enviornments do not have. If it was just the security we could do it role based, but the file locations are not based on role, so neither can this application be. – gbtimmon Jul 31 '12 at 16:13
  • You said it wasn't role-based, then you described what I consider role-based :-) So maybe you have two sets of roles, one for security and one for filesystem location type. You currently literally have lists of specific servers with different filesystem locations and different security constraints mapped to each server name? Hardcoded, or like in a property file? What I'm wondering is if you could for any particular server assign its "filesystem" option and its "security" option using System properties (similar to what @cjstehno suggested) and not have to look for specific server names at all. – dbreaux Jul 31 '12 at 17:00
  • I currently literally have lists of specific servers with lists of specific filesytems locations. Its unpleaseant, but dealing with other people's bad designs is 90% of my job. David a.'s solution look like it is going to work the best, it seem to be a Websphere specific implementation for what you and cjstehno describe which doesnt involve me having to go the admins and ask them to start the server a special way, only add some resources which they are much more likely to want to do. I share this server with about 20-30 apps at the same time. – gbtimmon Jul 31 '12 at 17:24
  • Fair enough. One small thought: if the filesystem locations are just some base directories, consider symbolic links to simplify that portion. – dbreaux Jul 31 '12 at 20:19

3 Answers3

2

Rather than making my application dependent on a (hardcoded) set of IPs, I'd use a simple String property bound to JNDI to identify each server.

Hardcoding an IP/hostname is usually not a good idea. Changes of infrastructure may happen right after you deploy your application :)

JNDI, on the other hand, is a standard way to get appserver's resources. Binding a resource (a string property) to JNDI can be done in WAS admin console and getting the property value from JNDI is easy. And IBM even published a tutorial about that.

david a.
  • 5,283
  • 22
  • 24
  • Good answer, but do you need any of the extra capabilities this provides over simply using System properties? That is, do you need different values across a single JVM? Or shared values across multiple JVMs in the same Cell? It's more code to access JNDI, and not easier to manage, IMO. – dbreaux Jul 31 '12 at 17:05
  • I think so - in a clustered environment. One might use such shared value to identify a test/prod cluster of JVMs. Another advantage could be to rebind the value without a need to recycle the servers. – david a. Jul 31 '12 at 20:08
1

Perhaps one way would be to check the name of the host using:

java.util.InetAddress.getLocalHost().getHostName()
Costi Ciudatu
  • 37,042
  • 7
  • 56
  • 92
  • Looks like this will work, but I am incredibly surprised that there does not seem to be a way to do this built into the api. – gbtimmon Jul 31 '12 at 15:45
  • I think the API is deliberately meant to make you unaware of the actual environment outside the servlet context -- and I think that's OK. If you really need to be aware of the actual host your app is deployed to, there may be some room for enhancements in your architecture. Moreover, the solution I suggested is not that reliable, it's just the only way I know for achieving what you asked. – Costi Ciudatu Jul 31 '12 at 15:53
  • On second look this is consitently returns the correct machine name. I suppose they didnt put it into the servlet api, because it was already in the java.util api. I couldnt find it because i was looking in the wrong places :D – gbtimmon Jul 31 '12 at 15:56
  • Well the application we are developing is a tool to control parts of the server enviorment that these applicaions are running on. So for us to try to be unaware of our enviornment would be pretty difficult. – gbtimmon Jul 31 '12 at 15:59
  • As I said, it's not 100% reliable; under certain circumstances it may return "localhost" and it may get interesting when you have several IP addresses for the same host. Check this answer for some tuning of the solution: http://stackoverflow.com/a/2381398/262683 – Costi Ciudatu Jul 31 '12 at 16:00
1

I had a requirement similar to this once and we used a system property. Basically you define the property in the startup command for the server with a -D argument:

-DserverId=serverA

and then in your servlet you can access it using:

System.getProperty("serverId")

You just give each server startup a different id.

Hope this helps.

cjstehno
  • 13,468
  • 4
  • 44
  • 56