This week's book giveaway is in the Reactive Progamming forum.
We're giving away four copies of Reactive Streams in Java: Concurrency with RxJava, Reactor, and Akka Streams and have Adam Davis on-line!
See this thread for details.
Win a copy of Reactive Streams in Java: Concurrency with RxJava, Reactor, and Akka Streams this week in the Reactive Progamming forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Junilu Lacar
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Knute Snortum
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Ganesh Patekar

Java/Tomcat - access denied trying to read an image on the server side to include in a PDF

 
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am trying to get an image to display on a pdf I am creating in java on the server side:

 

The image is stored in AwardTracker_NJE/WebContent/images. The error message I am receiving in the log is:



How should I be retrieving this image to use in this code to build the PDF please?

Kind regards,
Glyn
 
Rancher
Posts: 499
6
IntelliJ IDE Spring Fedora
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Does the folder have the right permissions?  Seems like its not a java issue
 
Saloon Keeper
Posts: 21128
131
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Did you create the TomcatSandbox directory? As Al said, it looks like Tomcat doesn't have access rights somewhere along that path.

In any event, it's not a good idea to add you own data directories to the Tomcat server directory. Such things tend to get lost when Tomcat gets updated. It's better to store them outside of Tomcat. In Unix/Linux, popular places for such directories include the /opt and /var/lib directory trees.

In any event, don't use relative file references in a webapp. They probably won't work reliably, if they ever work at all. The best way to obtain access to a data file that's actually in a WAR is to use the getResource() or getResourceAsStream() ServletContext methods. You shouldn't assume that a "file" in a WAR is really a file, so trying to get its path and reading it using filesystem functions may fail - or, again - not behave reliably.

The best way to get access to a data file that's outside of the application WAR is to use java file I/O based on an absolute path. NOT a relative path!

I like to make the base directory path for things like external image directories be a webapp environment property. That way I can set it according to the machine that the webapp is deployed on and use JNDI to get its value.
 
Saloon Keeper
Posts: 2722
354
Android Eclipse IDE Angular Framework MySQL Database TypeScript Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Glyndwr Bartlett wrote:The image is stored in AwardTracker_NJE/WebContent/images.


Image.getInstance("images/wosm.jpg"); will try and load the image relative to Tomcat's run(?) directory.

Since the image is below the WebContent directory in your WAR file, you will need to do something like this:
 
Glyndwr Bartlett
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tim,

The Tomcat is set up for my by the hosting company. So I can not adjust it. Also, this is a test area and I want to be able to deploy the war to production with all the information. The images are static as they are only used for the PDF headings. I am not a programmer by trade so any code samples would be appreciated.

Hi Ron,

I tried your code and have the error "Cannot make a static reference to the non-static method getClass() from the type Object".

Thanks for all your help,

Glyn
 
Tim Holloway
Saloon Keeper
Posts: 21128
131
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Ron McLeod wrote:

Glyndwr Bartlett wrote:The image is stored in AwardTracker_NJE/WebContent/images.


Image.getInstance("images/wosm.jpg"); will try and load the image relative to Tomcat's run(?) directory.

Since the image is below the WebContent directory in your WAR file, you will need to do something like this:



No.

Just No.  

If you store an image in a webapp (WAR), there is NO guarantee that you can open it using filesystem calls. In fact, in pure JEE, you cannot, although Tomcat's defaults are different.

That's because the official definition of a deployable WAR is a WAR file, which is a ZIP file, and you cannot open the "files" inside a ZIP file using standard filesystem calls, either.

You also should not attempt to locate WAR resources using classpath services. Not everything in a WAR is in its classpath and the classpath for a webapp is extremely messy.

The proper way to locate or read (NEVER WRITE!) a resource inside a WAR is to use the ServletContext getResource (which returns a URL) or getResourceAsStream (which is useful when you want to copy the resource to the response stream, as you would for javascript, css, and image "files"). ServletContext does offer a getRealPath() method that can return a filesystem path for the resource, but this is not a good option, because if the webapp server does not explode the WAR, that method will return null. Tomcat normally does explode WARs, but it's an option that I sometimes turn off, especially when I deploy the WAR to a location external to the Tomcat webapps directory.

Thus:


This is how you'd code it in a simple servlet. For a more complex case, where the servlet is invoking logic beans to do the dirty work, it's best to pass the servlet context along, since unless you're using JSF, it's not possible to get the context in a static manner.

Just as a side note, it is precisely because JEE deployables are officially WAR files, that the methods I mentioned are named "getResource" instead of "getFile". Because whether an element in the WAR's directory tree is a physical file or just an entry in a WAR file, it is always, in web terms, a "webapp resource".
 
Glyndwr Bartlett
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tim and Ron,

The answer is:



Where "ScoutTranscript" is the name of the class the code is in.

Thank you very much for your help, much appreciated.

Kind regards,

Glyn
 
Glyndwr Bartlett
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just saw Tim's reply.

I will try this as well.
 
Glyndwr Bartlett
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tim,

Errors on this code:

Syntax error on token "final", float expected
Cannot use this in a static context
Cannot invoke getResource(String) on the primitive type float

Kind regards,

Glyn


 
Ron McLeod
Saloon Keeper
Posts: 2722
354
Android Eclipse IDE Angular Framework MySQL Database TypeScript Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Holloway wrote:Just No.  


Yup - you're right - even though what I suggested will generally work with Tomcat, there is no guarantee of that and it is not a good practice.rather than
 
Ron McLeod
Saloon Keeper
Posts: 2722
354
Android Eclipse IDE Angular Framework MySQL Database TypeScript Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Glyndwr Bartlett wrote:Errors on this code ...


Since it appears like your code is in a utility class (ScoutTranscript) and not in a servlet class, you will not be able to call getServletContext() in that class, and will need to follow Tim's advise of passing the servlet context to the the class where you are going to use it.

Tim Holloway wrote:For a more complex case, where the servlet is invoking logic beans to do the dirty work, it's best to pass the servlet context along

 
Glyndwr Bartlett
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Ron,

Sorry not sure what you mean (I am not a programmer). Do you have an example please?

Kind regards,

Glyn
 
Tim Holloway
Saloon Keeper
Posts: 21128
131
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Ron McLeod wrote: even though what I suggested will generally work with Tomcat, there is no guarantee of that and it is not a good practice.



It's common practice, alas, but it's not good practice. It assumes too many things. Plus, it's not good policy to look uphill for stuff. Certain environments will actually change their roots to prevent looking too far uphill and, for example, up and over into a completely unrelated resource which they can then abuse.

I've had enough grief looking uphill for stuff using relative URLs, anyway. Things are never where I want them to be when I do that. And they break when I re-arrange my resource trees.
 
Tim Holloway
Saloon Keeper
Posts: 21128
131
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
By the way:


Syntax error on token "final", float expected



You must have something dangling from a previous statement to get that message. "final" is a perfectly acceptable qualifier when declaring a variable. Even float variables.

Also:


Cannot use this in a static context



Actually, a more informative message would say:


Cannot use "this" in a static context



I hate messages that blur keywords with literal values.  
 
Ron McLeod
Saloon Keeper
Posts: 2722
354
Android Eclipse IDE Angular Framework MySQL Database TypeScript Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Ron McLeod wrote:

Glyndwr Bartlett wrote:Errors on this code ...


Since it appears like your code is in a utility class (ScoutTranscript) and not in a servlet class, you will not be able to call getServletContext() in that class, and will need to follow Tim's advise of passing the servlet context to the the class where you are going to use it.

Tim Holloway wrote:For a more complex case, where the servlet is invoking logic beans to do the dirty work, it's best to pass the servlet context along


Glyndwr Bartlett wrote:Do you have an example please?


I don't know the details of where you need to get the image resource or how it is called, but the idea is since your utility class cannot reference the ServletContext directly, to pass a reference to the from the servlet to the utility class method so that it can be used to get the URL for the stored image.


Servlet
Utility Class
 
Tim Holloway
Saloon Keeper
Posts: 21128
131
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yup. That's the ticket. I prefer "/images/" for the value of IMAGES_LOCATION myself, as it makes the path-making expression simpler and highlights the fact that the IMAGES_LOCATION is a resource directory. Same net result, though.
 
You firghten me terribly. I would like to go home now. Here, take this tiny ad:
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!