0

In a POJO inside Java web app, how do I find the path to the root of the running website, so I can read a file there?

Remember, this is in a POJO, so I don't have:

  • getServletContext() (like in a servlet)
  • application (like in a JSP)

I've seen recommendations for System.getProperty("user.dir"), but this doesn't look right (on my laptop, it returns C:\Program Files\eclipse\eclipse, which is clearly not what I want).

The app will be deployed to Azure, so I won't technically know the path to the app in advance, this means I can't set it as a property or setting either. I need to produce it out of thin air, in real-time.

Other languages have globals:

  • PHP: $_SERVER['DOCUMENT_ROOT']
  • .NET: AppDomain.Current.BaseDirectory

You can then form a path by combining these values with the relative path from the webroot.

What is the equivalent for Java?

Deane
  • 8,269
  • 12
  • 58
  • 108
  • What exactly to you need? The resource location of `/` or of your web app e.g. `/mywebapp/`? These might be completely different locations, so I'm not sure if you examples for PHP and .NET are comparable. – Lothar Dec 28 '17 at 00:53
  • I want to read a file from the webroot. For that, I need the path. – Deane Dec 28 '17 at 00:53
  • you can't do it, the files are protected from the web and inaccessible unless you know the location of the system files. – Roman C Dec 28 '17 at 00:54
  • And if the webroot is served from a war-file? – Lothar Dec 28 '17 at 00:55
  • I can't be impossible to read the contents of a file. I'm doing it now, from a servlet, but I want to move this code into POJO, so I'll lose `getServletContext()`, hence my question. – Deane Dec 28 '17 at 01:00
  • This is a http://xyproblem.info, please take a step back: why exactly do you need to know that path? There's no sensible real world use case for that, so you're clearly asking how to achieve the wrong solution to the problem you initially attempted to solve. If I were to do a guess, this is the answer you're really looking for: https://stackoverflow.com/q/18664579 – BalusC Dec 28 '17 at 09:59
  • @BalusC I am using OpenNLP to do some text processing. It requires some "training" files when it inits. It reads from these files to configure itself. So, my question really is: where should I put these files so that I can easily read them into an `InputStream` from a POJO which is wrapping the OpenNLP classes? – Deane Dec 28 '17 at 14:06
  • @BalusC After doing some reading, I think the right solution is to compile the files into the JAR. These files won't change (and if they do, I will redeploy the app). Does this sound reasonable? – Deane Dec 28 '17 at 15:40
  • Indeed, just put in classpath and use `ClassLoader#getResourceAsStream()`. See duplicate for various techniques. – BalusC Dec 28 '17 at 18:08
  • The solution was to put the file right alongside the class, and then do this: `InputStream content = ClassName.class.getResourceAsStream("file.txt");` – Deane Dec 29 '17 at 02:37

1 Answers1

0

I don't think that there is something comparable to the variable in PHP or .NET simply because there might be multiple webroots on a system: One being used for plain connections and the other for TLS connections or if you set up multiple HTTP-server within an application (I'm doing that with Jetty on a regular basis)

So a "global variable" like a system property can't work here.

My idea of solving that is actually saving the ServletContext or whatever is available within a non-POJO-class (like a servlet) to some static member in one of your classes that are part of the webapp, so you can access it from your POJO and get the webroot from it. As mentioned in one of my comments, that root might be inside a WAR-file so you shouldn't expect java.io.File to actually work.

That should work even if you use the same webapp multiple times within the same server (or across multiple servers in the same VM) because these webapps should use different class loaders so that storage class should be loaded per webapp.

Lothar
  • 5,323
  • 1
  • 11
  • 27
  • I'm going to accept this because it did work. I passed the `ServletContext` into the POJO, and it used that to find the file. Not the most elegant solution, but it worked. See my last comment on the original question for the solution I actually used. – Deane Dec 29 '17 at 02:38
  • @Deane Thanks for accepting the answer. Your solution you described in the comment above has nothing to do with this particular question, though ;-) – Lothar Dec 29 '17 at 10:12
  • I agree. My basic approach was all wrong. Your answer above answers my question, but my question was foundationally bad. – Deane Dec 29 '17 at 18:57