An enterprise bean must not use the java.io package to attempt to access files and directo-ries in the file system.
This restriction hold for all the EJB's?
I mean if I know the deployment env details ( i.e os and its file system ), can I use java.io package to read files from the OS in my EJB? ( here I'm compromising that if I have to deploy this EJB on to a different OS then I need to modify the code)
Please comment on this as I'm not clear about this filehandling point in EJB spec!
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.
Normally, a well-behaved and standard EJB container should not allow beans to access the filesystem. Table 19 (p. 498) says that one responsibility of the Container provider is to deny file access.
Now, you can change that policy if you want but your beans will not be portable.
Remember that we're talking certification here -- and the cert is 100% about "Do you know how to write beans to the spec." Whenever you read a question, you can assume that there is an implicit sentence at the beginning that says:
"Assuming you want to make vendor-portable components..."
Most of the time, when it really mattered (like with programming restrictions - e.g. file access), we tried to include something like that in the question itself, but if we didn't, you can be certain that we are NEVER expecting you to answer based on vendor-specific exceptions or extensions to the spec, even if virtually *all* container vendors do it.
The Spec Is Your Friend. (well, for getting the final word, anyway)
The exam will NOT ask you about *anything* that is not in the spec. So, the spec isn't the best place to *learn* how it all works, but if it isn't in the spec, you will not be expected to know it. However, remember, the exam will expect you to understand the full implications of what is in the spec, so you are presented with problems that expect you to know the right answer based on your underlying knowledge of the spec.
Remember, we still have a non cert-related EJB forum, so you're more likely to get vendor-related answers over there...
We came up with this fantastic design where we receive a MQ Message in XML format. We determine version of the message using the JMS properties of message then we read, the corresponding XML specification file. This XML file contains the record layout and validation rules for converting the XML message to Cobol record format. The XML file is parsed into a DOM tree and we create the Cobol record using XPATH.
Eventually we will put the XML specification file into a database record. Put to getit all working we decided to simply read the file.
And now you guys say reading a file just aint't done
And now you guys say reading a file just aint't done
Ah. The wonders of neverending debate...
You can definitely read a file from within an EJB. It's not recommended and the next version of your appserver might (that's a big if) render your EJB invalid by preventing I/O access using black magic, but if you're willing to live with it then go for it.
For every techie saying "no I/O in EJBs" (me included) there are a hundred who are doing it without problems.
What I'm trying to say is, don't make a fuss about it. If it works, it works.
Is it REALLY against the spec if you load a resource (a file in your classpath) via your classloader?
We use this kind a lot:
JDJ: I believe the "recommended" strategy would be to develop a J2EE Connector module for accessing the file system...
"The enterprise bean must not attempt to create a class loader; obtain the current class loader; set the context class loader..."
"These functions are reserved for the EJB Container... could compromise security and decrease the Container's ability to properly manage the runtime environment."
So, if I'm understanding this thread correctly, using the classloader as a back door is not an option if you're writing to the spec, for portability.
Since we're talking about the exam, then you have to be very clear about the restriction. EVERYTHING on the exam comes with implicit "for portability" stuck in.
But I don't give up. What about URL then?
So no use of java.io package. And I didn't touch the URLStreamHandlerFactory ;-)
The only drawback I can see right now is: the container doesn't have to provide a stream handler for "file://" URLs.
But you can keep your files on a private http server right beside your app server (or the app server can do this for you).
The Connector API sounds interesting for me. I really would like to see a provider for file systems. Maybe there is already one around on the net. I'll have a look.
There a three vendors providing resource adapters for Flat files, see
J2EE Connector Products
What about JNDI? No, I don't think this is a good place to put files in.
Relational DB with JDBC? Makes editing of the files a little bit awkward.
I'm sure there is a good and portable way to do this.
[ August 20, 2003: Message edited by: Peter Storch ]
[ August 20, 2003: Message edited by: Jack Conway ]
No, I'm sure that the reasoning behind the restriction is due to replicabilty. Your bean could write to the file during one method invocation, yet by the time the next method is invoked, the method call is directed to a different bean instance, on a different VM, on a different server - hence a completely different file.
Why is it not allowed to use static attributes in an EJB? For the same reason as far as I know.
Why can't EJBs read and write files and directories in the filesystem? And why can't they access file descriptors?
Enterprise beans aren't allowed to access files primarily because files are not transactional resources. Allowing EJBs to access files or directories in the filesystem, or to use file descriptors, would compromise component distributability, and would be a security hazard.
Another reason is deployability. The EJB container can choose to place an enterprise bean in any JVM, on any machine in a cluster. Yet the contents of a filesystem are not part of a deployment, and are therefore outside of the EJB container's control. File systems, directories, files, and especially file descriptors tend to be machine-local resources. If an enterprise bean running in a JVM on a particular machine is using or holding an open file descriptor to a file in the filesystem, that enterprise bean cannot easily be moved from one JVM or machine to another, without losing its reference to the file.
Furthermore, giving EJBs access to the filesystem is a security hazard, since the enterprise bean could potentially read and broadcast the contents of sensitive files, or even upload and overwrite the JVM runtime binary for malicious purposes.
Files are not an appropriate mechanism for storing business data for use by components, because they tend to be unstructured, are not under the control of the server environment, and typically don't provide distributed transactional access or fine-grained locking. Business data is better managed using a persistence interface such as JDBC, whose implementations usually provide these benefits. Read-only data can, however, be stored in files in a deployment JAR, and accessed with the getResource() or getResourceAsStream() methods of java.lang.Class.
Why can't I use nonfinal static fields in my enterprise bean?
Nonfinal static class fields are disallowed in EJBs because such fields make an enterprise bean difficult or impossible to distribute. Static class fields are shared among all instances of a particular class, but only within a single Java Virtual Machine (JVM). Updating a static class field implies an intent to share the field's value among all instances of the class. But if a class is running in several JVMs simultaneously, only those instances running in the same JVM as the updating instance will have access to the new value. In other words, a nonfinal static class field will behave differently if running in a single JVM, than it will running in multiple JVMs. The EJB container reserves the option of distributing enterprise beans across multiple JVMs (running on the same server, or on any of a cluster of servers). Nonfinal static class fields are disallowed because enterprise bean instances will behave differently depending on whether or not they are distributed.
It is acceptable practice to use static class fields if those fields are marked as final. Since final fields cannot be updated, instances of the enterprise bean can be distributed by the container without concern for those fields' values becoming unsynchronized.
[ August 21, 2003: Message edited by: Jack Conway ]
Read-only data can, however, be stored in files in a deployment JAR, and accessed with the getResource() or getResourceAsStream() methods of java.lang.Class.
Hmm, so the java.lang.Class has also these methods.
I'm really wondering, if the calls to these methods are allowed withing an EJB. Because the API doc of java.lang.Class says that the Class delegates to the ClassLoader which in turn is not allowed to use from an EJB.
Is this advice from EJB 1.1 still available in the EJB 2.0 spec? I've not checked yet.
The EJB2.0 spec only says "no use of java.io", and it says this is because the file system API is not well suited for business components to access data! It doesn't mention getResourceAsStream at all.