When EJB specification says 'must not...'

Discussions

EJB programming & troubleshooting: When EJB specification says 'must not...'

  1. When EJB specification says 'must not...' (18 messages)

    Hi everyone,

      Both EJB 1.1 and EJB 2.0 specifications say: 'An enterprise Bean must not use the java.io package to attempt to access files and directories in the file system.' What if I must use EJB to process some data that are not in a database? For example, is it possible that we have a stateless EJB that is used to process daily sales reports (could be as a .txt file) by distributed stores and save the data into a database on the server side? It seems make good sense, but how to implement it if the EJB is not supposed to access file system?

    PC

    Threaded Messages (18)

  2. Pengju,

    Good question. The easy answer is to forget what the spec says and do it anyways. Most containers do not have runtime enforcement of that rule. So, it should work without problem.

    You'll find that there are many things in the EJB spec which say "must not do". Personally, I think that it is just another reason to show why EJBs are so limiting.

    Forbidding the usage of the I/O and Thread libraries seem to be among the worst limitations.

    Good luck,

    Rick
  3. Limiting the use of the thread libraries is specifically so that the container can control which resources are in use. Threads, in particular the number of threads, can dramatically affect the performance of your system, so this limitation is quite understandable.

    The I/O limitation is more due to the fact that under many OS these operations block (Windoze for instance) and you could theoretically lock up the thread in the server, which is not nice. However, as already mentioned, this is one of the rules that people frequently ignore.

    If you want to really stick to the spec, have a command line that publishes the contents of the .txt files to JNDI (if small) or to the database if not.

    Chz

    Tony
  4. Tony,

    My point is that the application server should not be limiting two core components in the Java language (I/O and Threads). The useful applications for multi-threading and I/O are endless. To completely exorcise them from the EJB spec is not a good thing, IMHO.

    I've been using Java/CORBA for a long time... and doing these very things. And it works FINE. I don't need an application server to control my worker threads. Of course, as a programmer, you always have to be _responsible_ about thread and I/O usage.

    But to completely remove them is overkill, I think.

    Regards,

    Rick

  5. I won't argue about I/O because I agee that it's a little too much..but threads...I don't know..once you start clustering things, replicating objects, etc. you start running into problems. people often suggest instead of threads use async messaging, it will solve 90% of your problems.

    --
    Tinou Bao
    www.tinou.com
  6. Heres the deal. If you start creating threads and such like inside any container that, in theory, is responsible for managing the resources at your disposal, then do not get upset if it doesn't manage the resources properly.

    From what you say, you have done the above, and it has worked FINE (to use your exact words.)

    My point is that nothing comes for free. If you really don't want to have to think about things, then you have to obey the rules, to the letter. If you are prepared to think (which it sounds like you are from what you say) then perhaps you can bend them.

    But the specs are written for everyone, not just those that think! :-)

    Basically, the spec should probably say "If you do this then the container makes no gauruntees........." etc rather than simply "Thou shalt not..." Would you agree?

    Chz

    Tony
  7. Tony,

    I agree completely.

    For those of us programmers who are willing to 'think' about what we're doing... give us a facility to use native I/O and threads. For those that aren't willing to 'think'... well... they can use the 'vanilla' configuration for their app servers.

    The spec should say something like : "The container shall not, by default, permit the usage of native I/O and threads, but if the developer desires to use them, the container should allow it, but not be responsible for the management of these processes."

    Regards,

    Rick
  8. I avoid disk i/o for following resons.... most of the times the applications i'm designing have to handle far too many requests to readily indulge into disk i/o. I cannot afford a session bean going to the disk reading or writing stuff off of it... if I need to do this I use a ServiceActivator pattern dispatching requests to message-listeners outside my container. Second... almost always the app-servers are clustered... If they are not clustered today...they will be tomorrow... so I tend not to depend on local file systems for files.... I think it's a good idea to have a small framework to acess local i/o that can be used asynchronously rather than accessecing them directly... the advantage of this approach is the higher speed writes available to the system.... reads are a little painful... but i reduce the affect by writing small facades that encompass this complexity... so to the develepor the code looks like

    AsyncFileWriter afw = new AsycFileWriter
        (<jms resource details>);
    afw.write("This is a test message");

    AsyncFileReader afr = new AsyncFileReader
        (<jms resource details>);
    String something;
    do{
        something = afr.getNextLine();
        process(something);
    }(while something != null)

    I'd use byte arrays for binary data in case i needed it.
  9. Another advantage of using this approach is that it lets me transact writes to a file.... (since i can transact JMS messages) hence if you'r application needs to track a set of operations....but log details for only those that are sucessful...voila!
  10. Most of the time, disk I/O is very limited. Usually only reading or writing small text files (properties, INI, cfg files). I have written different kinds of log managers which run in a background thread and therefore do not block. Much more efficient, and much cleaner.

    I handle socket-based I/O the same way.

    I use multi-threading when doing any kind of operation that is blocking such as I/O. This allows the container to continue processing requests as normal.

    With multi-threading, one does not have to worry about the blocking nature of processes. And this is easily accomplished without having to go outside with container... which I think is inconvenient and inefficient. Such as using Messaging. Also, messaging does not give you the kind of control you have with native threads and thread groups.

    I think multi-threading is a far superior approach than any other for the applications we're talking about.

    Regards,

    Rick

  11. Rick,

      So you did start your own threads in your EJB for reading/writing small text files and did not get in trouble? That is a good news for me. I really feel that I need to start a separate thread doing some update every certain time and I certainly can not stop the whole process. My senario is: I have a vector that contains requests retrieved from database and methods processing the requests in a stateless EJB. The vector needs to be updated continuously because new requests may be added to the database any time. So I made the vector a static member and started a thread to update it every 5 minutes in ejbCreate(). But it seems that I'm still in trouble because the specification also says an EJB must not use read/write static field to gurantee the portability. However, what if I don't really care portability in this case? I used VAJ and did not get any warnings about this. (Sometimes you really just want something work and only work in a certain environment.) What would you say?

      I would like to hear comments from all also.

      Thanks.

      PC
  12. Pengju,

    In some EJB servers you can kick off native threads. In some cases... the EJB server will not permit it at runtime. Most CORBA servers will permit native threads (such as Visigenic's ORB).

    As far as the 'static' question... you've come across (yet another) "must not" rule for EJB... and one that most of us break. It is the 'no singleton' rule.

    Just keep your statically held class or singleton. It should work fine.

    Lots of people use singletons or static classes on the server-side to hold application properties or global 'stacks' of objects. This is very common.

    Good luck,

    Rick
  13. hey a question... if indeed iwere to start these threads... and do local disk io... how would i figure out if this is the same disk file i was using before.. i.e. lets say the session migrates to a different machine in the cluster... what would i do?
  14. Welcome to one of the reasons they don't want you to do threading and disk I/O!

    If you are in a cluster then you'll have to replicate the files (or mount them using NFS (ug!) or connect the servers to a disk array with fibre) to solve that problem. If you are using stateful session beans under WL 5.1.0 then your bean is server affine any way and won't move. Under 6.0 it can so you have the problem back again.

    Chz

    Tony
  15. Tony,

    The issue of sharing a file between clusters has NOTHING do with your argument against multi-threading or using native I/O.

    These things have been done for years in C/C++ servers. Even in Java-based clustered servers. And continue to be so. Much to your dismay.

    This is a *common* issue to deal with for ANY kind of clustered server. Web server, database, app server... etc.

    Don't bring it into the EJB argument. It has NOTHING to do with EJBs.

    Regards,

    Rick
  16. With respect you are missing my point. I did not say it was relevant to EJB. I said it was relevant to clustering, something applied to many things. It just so happens that the way EJ B tries to tackle the problem is by stopping you doing it in the first place. In other words problem avoidance, not problem solutions.

    Bottom line, if you ask the container (whatever kind) to access things outside the container, and that container is clustered, then either you have to cluster the external things as well, or you have to do something like server affinity.

    That's just my opinion, and it has NOTHING to do with EJB, it is purely related to any environment where you are talking to a clustered container which you are programming in such a way as it accesses resources external to the container.

    Chz

    Tony
  17. Aditya,

    In any kind of clustered solution, common files on a filesystem should also be clustered, so that they can be shared.

    This is a very common solution. Clustered applications often will have a common, clustered disk farm which holds global application properties files, or log files.

    I wouldn't use NFS. As it is very slow. There are other good clustering solutions out there which offer excellent performance with little latency. Most operating systems have native capabilities to share disk files. Even Win32... with its Network Drive mapping.

    Good luck,

    Rick

  18. As far as singetons go, use them use them use them. Just accept that it's only a singleton per virtual machine and make sure that doesn't hurt you in a clustered environment.

    As with all things inside EJB, as long as you think about it first you'll be fine! :-)

    Chz

    Tony
  19. Another comment... I've been observing..and this is just my personal opinion.... most of the times when making design decisions, we know... atleast I do that it might not be the best way.... but I do it any ways since it saves me writing code... in other words... if the designer IS the developer, the design will be biased towards laxer coding (taking shortcuts to solve problems) something our project-managers should keep in mind before they make us code :^>