tags:

views:

298

answers:

3

Hi all,

I have a java EE application EE5 EJB3. I develop using NetBeans 6.7 and GlassFish 2.x I need to have a configuration file (*.xsl, *.xml) that is deployment/client specific.

My questions are:

1) where do I put files that are external to the ear file?

2) How do I load the files into a session bean? can I use injection?

I manage to inject a @Resource for the file name using the ejb-jar.xml.

Many thanks in advance. G.

+5  A: 

I guess this is not what you are expecting but the right answer is that you shouldn't do it! According to the EJB specifications and more precisely the Programming Restrictions:

An enterprise bean must not use the java.io package to attempt to access files and directories in the file system.

And this statement is followed by this explanation:

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.

The reasons behind this statement are:

  1. Accessing the file system isn't transactional and would compromise component distributability.
  2. Accessing the file system from an EJB would compromise its deployability (the resource isn't under the EJB container's control and the EJB can't be moved easily in a cluster).
  3. Accessing the file system is a potential security hole.

Now that you know this, if you still want to do what you had in mind and if your EJB container doesn't restrict using classes from the java.io package, then I would put a read-only file on the classpath, preferably in a JAR, and access it using the getResource() or getResourceAsStream() methods of java.lang.Class. But really, you should keep the specification in mind, it's there to help you build portable applications.

Pascal Thivent
Thank you pascal.Can you suggest an alternative way to solve this requirement?many thanks.G.
Gadi
We gave you already have hints in this page (JDBC, JNDI properties) but I'll let ewernli answer this question as you accepted his answer.
Pascal Thivent
Hi Pascal. I need to be more specific :) . I need to load an xsl file to translate xml submitted via web-service or http post. each client will need the file to be a bit different. I used JNDI and @Resource injection but I can not see how an xsl file can be loaded this way.many thanks. G.
Gadi
Just to clarify: how do you distinguish the clients? Are you going to deploy several EARs? Do you use Metro?
Pascal Thivent
Gadi
+1  A: 

See this question: Process files in Java EE.

The specification forbids file access using java.io, it does not forbid file access in general.

One of the main reasons that files cause problems in enterprise applications is that they are hard to use safely and efficiently in a multi-user environment. In particular, file locks can heavily constrain scalability.

Using a class loader to read a configuration file once per session as suggested by Pascal is unlikely to cause problems on most application servers, except possibly in the case of hot deployment.

JNDI properties can be used as an alternative to a configuration file. JNDI properties are defined in the deployment descriptor and bind a value to a JNDI name at deployment time. The application can look up the value from inside the application using the JNDI name.

richj
+2  A: 

If you can assemble one EAR per target deployment (maybe maven profile can help in this area), then you can then load it like a resource.

Another option would be to have a look at J2EE Application Deployment Specification (JSR-88) to have one EAR with N deployment plan per environment.

You can also decide to store the file on the filesystem (even though it's prohibited). If you want the path to be in the ejb.xml then you need again to assemble or deploy the EAR in different ways - no big gain then. Another option would then to use a Glassfish Custom JNDI Resource to have the possibility to configure the path right from the admin console. The your app. can load the file according to the path that is configured.

ewernli
Thank you for your answer.If I take the above advise and do not use the file system, can you explain what will be an alternative strategy?Can I package the files in a lib and lint it as external library from the main era?this way I can prepackage the lib only per deployment.many thanks. G.
Gadi
Not sure what you exactly mean, but normally, if you package your client specific files in a .jar and place the .jar in the .ear, then you should be able to load the file like a resource.
ewernli
hi, yes, this is what I meant. I assume I can have a default jar file that have the default files and then for each client I can replace only that jar in the ear? many thanks. G.
Gadi