File access in EJB
File access has always been a controversial activity within EJB-based applications because of the restrictions placed upon bean providers by the EJB specification. The part of the specification relevant here is under the section entitled Programming Restrictions, and it states the following about accessing the filing system.
An enterprise bean must not use the java.io package to attempt to access files and directories in the file system.
This is a fairly specific statement, and is followed up by a short explanation of why this is the case.
The file system APIs are not well-suited for business components to access data. Business components should use a resource manager API, such as JDBC, to store data.
While this explanation highlights a key reason for not using file I/O, I think that there is much more to this. However, although this is a well known restriction, actually finding more information on this is a time consuming task. So, in the quest for knowledge, I did some digging and came up with the following reasons why file I/O is "a bad thing"TM.
- The WORA mantra of Java and J2EE means that there might not actually be a filing system to access. I've seen various comments saying that the J2EE server might be running on some device that doesn't have a filing system, or the application server doesn't have access to the filing because it's deployed in, for example, a database server. Although this is a valid reason, I don't think that this applies to most projects.
- Access to files isn't transactional. Yes, typically, files aren't transational resources and when building enterprise systems, you usually want to be sure that some information has been correctly and accurately stored, hence the use of relational databases and the like.
- Accessing file systems is a potential security hole. If we look at how other resources (e.g. JDBC DataSources, JMS Topics, etc) are accessed, it's usually through JNDI. To ensure that only authorised parties can access these, we typically have such resources protected by some sort of authentication mechanism, be it a username/password combination, or an SSL certificate. The problem with filing systems is that they are much more open and it's harder to control access. One solution is to lock file access via the operating system, and another is to use the Java security model to restrict access to only a specific part of the disk. If you are going to access the filing system from your business components, then locking down access will help to make the system more secure and resilient to attacks.
So then, how are we supposed to access files from EJB? Many people advocate the use of an intermediary Java class to wrap up the file access, believing that the EJB specification only disallows access from the bean class itself. Is this true? I'm not convined because all the same reasons apply. The specification itself presents an answer, and that answer is to use a resource manager so that we can treat file access as a secure, transactional, pooled resource. One such implementation is a J2EE Connector Architecture (JCA) adapter that you write, deploy and configure to access your filing system. In fact, some vendors have already built JCA adapters that access flat files and these are particularly useful if you have to access the outputs of legacy, mainframe systems.
Of course, many types of file access can be worked around. For example, configuration information can be placed in LDAP, JNDI, a database, or even properties files delivered inside your JAR files that get loaded as a resource through the classloader. In those circumstances where accessing files is a requirement, then other solutions include loading the file through the servlet container, having it sent to the EJB tier via messaging, downloading the file from a webserver through a socket connection and so on.
These are all workarounds for the programming restriction but at the end of the day I think you have to be pragmatic. Many projects do utilise file access from within the EJB tier and their solutions work. Although the EJB specification imposes a restriction, in reality many vendors choose not to enforce this, meaning that using the
java.io package for accessing files is possible. Whatever solution you come up with, you should ideally keep the specification in mind. It's there to help you build portable and upgradable applications, but pragmatism should be employed. Hopefully a future version of the EJB specification will address this issue in more detail and this controversy will become a thing of the past.