Asked  7 Months ago    Answers:  5   Viewed   27 times

I am trying to generate a XML file and save it in /WEB-INF/pages/.

Below is my code which uses a relative path:

File folder = new File("src/main/webapp/WEB-INF/pages/");
StreamResult result = new StreamResult(new File(folder, fileName));

It's working fine when running as an application on my local machine (C:UsersuserNameDesktopSourceMyProjectsrcmainwebappWEB-INFpagesmyFile.xml).

But when deploying and running on server machine, it throws the below exception:

javax.xml.transform.TransformerException: java.io.FileNotFoundException C:projecteclipse-jee-luna-R-win32-x86_64eclipsesrcmainwebappWEB INFpagesmyFile.xml

I tried getServletContext().getRealPath() as well, but it's returning null on my server. Can someone help?

 Answers

78

Never use relative local disk file system paths in a Java EE web application such as new File("filename.xml"). For an in depth explanation, see also getResourceAsStream() vs FileInputStream.

Never use getRealPath() with the purpose to obtain a location to write files. For an in depth explanation, see also What does servletcontext.getRealPath("/") mean and when should I use it.

Never write files to deploy folder anyway. For an in depth explanation, see also Recommended way to save uploaded files in a servlet application.

Always write them to an external folder on a predefined absolute path.

  • Either hardcoded:

      File folder = new File("/absolute/path/to/web/files");
      File result = new File(folder, "filename.xml");
      // ...
    
  • Or configured in one of many ways:

      File folder = new File(System.getProperty("xml.location"));
      File result = new File(folder, "filename.xml");
      // ...
    
  • Or making use of container-managed temp folder:

      File folder = (File) getServletContext().getAttribute(ServletContext.TEMPDIR);
      File result = new File(folder, "filename.xml");
      // ...
    
  • Or making use of OS-managed temp folder:

      File result = File.createTempFile("filename-", ".xml");
      // ...
    

The alternative is to use a (embedded) database or a CDN host (e.g. S3).

See also:

  • Recommended way to save uploaded files in a servlet application
  • Where to place and how to read configuration resource files in servlet based application?
  • Simple ways to keep data on redeployment of Java EE 7 web application
  • Store PDF for a limited time on app server and make it available for download
  • What does servletcontext.getRealPath("/") mean and when should I use it
  • getResourceAsStream() vs FileInputStream
Tuesday, June 1, 2021
 
freeMagee
answered 7 Months ago
28

I had a similar challenge and created a single file that defines constants for all the relevant paths that I want to be able to call as-needed. I include this file in all my pages (I define the $urlRoot so that this will work in all environments and is moveable do different domains, etc):

File: pathData.php (added MENUDIR for your example):

$baseDir = dirname(__DIR__) . '/';
$rootUrl = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . '/';
define('ROOTURL', $rootUrl);
define('BASEDIR', $baseDir);
define('INCLUDES', $baseDir . 'includes/');
define('INCLUDESURL', ROOTURL . 'includes/');
define('JQUERYURL', ROOTURL . 'includes/jquery/');
define('MENUDIR', ROOTURL . 'views/general/');

Then in each file, I include that file with an include that includes the relative directory path. For example:

include("pathData.php");
or
include("../pathData.php");
or
include("../../pathData.php); 
etc.

So in your case you could (depending on where your pathData file is):

include("../pathData.php");
include(MENUDIR . "navbar.php");
etc...
Saturday, May 29, 2021
 
Octopus
answered 7 Months ago
57

In the file that has the script, you want to do something like this:

import os
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'relative/path/to/file/you/want')

This will give you the absolute path to the file you're looking for. Note that if you're using setuptools, you should probably use its package resources API instead.

UPDATE: I'm responding to a comment here so I can paste a code sample. :-)

Am I correct in thinking that __file__ is not always available (e.g. when you run the file directly rather than importing it)?

I'm assuming you mean the __main__ script when you mention running the file directly. If so, that doesn't appear to be the case on my system (python 2.5.1 on OS X 10.5.7):

#foo.py
import os
print os.getcwd()
print __file__

#in the interactive interpreter
>>> import foo
/Users/jason
foo.py

#and finally, at the shell:
~ % python foo.py
/Users/jason
foo.py

However, I do know that there are some quirks with __file__ on C extensions. For example, I can do this on my Mac:

>>> import collections #note that collections is a C extension in Python 2.5
>>> collections.__file__
'/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-
dynload/collections.so'

However, this raises an exception on my Windows machine.

Tuesday, June 1, 2021
 
MKM
answered 7 Months ago
MKM
24

Instead of returning StreamContent as the Content, I can make it work with ByteArrayContent.

[HttpGet]
public HttpResponseMessage Generate()
{
    var stream = new MemoryStream();
    // processing the stream.

    var result = new HttpResponseMessage(HttpStatusCode.OK)
    {
        Content = new ByteArrayContent(stream.ToArray())
    };
    result.Content.Headers.ContentDisposition =
        new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
    {
        FileName = "CertificationCard.pdf"
    };
    result.Content.Headers.ContentType =
        new MediaTypeHeaderValue("application/octet-stream");

    return result;
}
Tuesday, June 1, 2021
 
Sendy
answered 7 Months ago
10

I believe the Java EE Java stack is actually very good. There are a few reasons explaining the low productivity of Java EE:

  • Being “the enterprise stack”, it is often used to create boring, ugly, “good enough” applications and, in general, enterprises tend not to attract great developers who love programming, and think and care about what they do. The quality of software in the enterprise world is not great.
  • Being the enterprise stack where the money is, software vendors try to sell something to them. They create huge, complex and expensive solutions not because they are good, but simply because they could sell them to enterprises.
  • Enterprises are often very risk averse and everything they do better be “standardized”. Standards are created either after some technology proved to be successful or before. In both cases, it’s bad for enterprises (and Java). Enterprises end up using either good technology too late or a downright failed technology. The latter case is also very dangerous because it creates a false perception that a technology (otherwise a complete failure) must be good if it is standardized and everyone is using it.
  • Historically, Java EE platform seemed to have attracted a lot of architecture astronauts and developers in big companies promoted to architects whose only purpose was to create more layers, more frameworks, more abstractions and more complexity.

It’s not that there are no good Java tools and frameworks; it’s that there are too many bad ones, too many over-engineered ones, too many bureaucratic processes and methodologies, too many useless standards.

In such a messy world it’s not just the particular selection of tools you choose that affects your productivity. It’s mainly about you, about your values, about how you can reject the majority of solutions proposed to you by the community, vendors, co-workers and managers. It’s about you going against the current, about your common sense, about you questioning every mainstream belief and “best practice”.

That said, tools alone are not going to change your productivity much, and conversely, the right people can be productive with inferior tools too.

My advice:

  • Don’t use a technology only because it’s standard, because everyone uses it, or because it’s officially recommended by Sun. Use a technology only if you personally think it’s the best tool for your job. This way you may find yourself rejecting technologies such as JSF, JSP, Web services, JMS, EJB, JTA, OSGi, MDA.
  • Keep it simple, use your common sense, question everything. Do you really need to publish your objects for remote access? Do you really need to create another abstraction layer so that you can switch from Hibernate to TopLink? Do you really need to convert your data to/from XML ten times every time you need them? Do you really need XML schema? Do you really need everything to be configurable are interchangeable? At runtime? By non-developers?
  • Keep the process simple. Be agile. Do you really need that documentation? Do you really need to describe every screen in a huge table, have it approved, type it in to some home-made tool and then generate JSP? Do you have competent programmers or you design everything first and programmers only “translate” to Java?
  • WYSIWYG design of HTML doesn’t work.
  • Graphical programming in general doesn’t work. This includes UML as blueprint and UML as programming language, MDA, drawing page flow diagrams. Code generation is bad.
  • Never design a framework prior to using it, always harvest a framework.
  • Prefer frameworks that have only little XML configuration.
  • Strive for low LOC count. Look at actual characters in your code. Is every character important? Think. What can you do to make your code smaller? Do you need that class? What does it do? Why do you need to do that?
  • Testing is not sacred cow; you don’t need 100 % test coverage. Test only what makes sense. If it’s difficult to test, make it simpler; or don’t test it at all. Don’t test visual appearance.

And finally, some concrete Java recommendations:

  • For presentation layer try Tapestry. Why do I love it? Because with Tapestry you can create beautiful code. It’s designed specifically for that, so that your code can be beautiful. Your code. By beautiful I mean everything that matters – it’s short, easy to change, easy to read, easy to create your abstractions, and still flexible, it doesn’t try to hide the fact that you are developing for the web. Of course, it’s still you who makes your code beautiful.
  • Feel free to use Hibernate, especially for CRUD and large apps. Don’t bother with JPA. It’s not a silver bullet though, with ORM you are always going to trade one set of problems with another.
  • Only a little Spring, you shouldn’t need much since you’ve carefully avoided all the Java EE traps. Use dependency injection sparingly.
  • After all of that, you may find the Java language too verbose and not very helpful when abstracting away you copy/pasted code. If you want to experiment, try Scala. The problem is that the main selling point of Scala is that you get all the benefits of modern languages while still keeping type safety, and at the same time, there is no solid IDE support. Being used to super-cool Java IDEs, it doesn’t make much sense to switch to Scala unless there’s an IDE support that is stable and reliable. Stable enough is not enough.
Friday, September 3, 2021
 
TacB0sS
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share