Folks, There's a customer I'm working with that is trying to move from a J2SE architecture to a J2EE architecture, and in the process of helping them do that, I've realized that most of the diagrams about how J2EE "sits on top of" J2SE are, in fact, wrong. I'd really say that J2EE sits on a subset of J2SE, since there are a number of things you should NOT do in J2EE that are perfectly valid in J2SE. So, I'm trying to compose a "top 10 things that you can do in J2SE you shouldn't do in J2EE" list. Here are my first ideas -- I'd welcome additional contributions or comments: (1) Don't create your own threads. This is actually restricted in the EJB specification (EJB 2.0 Spec, Chapter 24.2.1) but it's not a great idea in the Web Container either. There are several reasons for this: First, if a web application creates a thread, it's undetermined what security principal is associated with that thread -- that means that you have to separately handle authentication into any EJB methods you may want to use. Second, thread pools are actively managed by the web container; if you create your own threads, you run the risk (if not properly managed) of starving the application server of threads. What's more, transaction contexts are associated with threads -- if you use JTA in your servlet, you may find that access outside of the servlet thread is outside the transaction. (2) Don't rely on singletons. The problem here is one of classloaders. In J2SE it's easy to assume that your program has a single classloader, and that all statics are shared. This is not so with J2EE. Each J2EE module may have its own classloader, and most application servers have a hierarchy of classloaders for other purposes. Thus, it's difficult to determine if a singleton is really one instance, or two, or three, or... (3) Don't use DriverManager. When you are building standalone applications that use J2SE you are responsible for obtaining your own connections to JDBC databases. However, you have to be aware of the resources that a JDBC connection takes up. Each connection can occupy up to a meg of memory, and what's more, there are only a limited number of connections that each database can handle. Thus, sharing them is the best approach to take when there are potentially hundreds or thousands of users needing access. This is what J2EE allows through DataSources in both the EJB and web container. (4) Don't use files. This is because a J2EE application may very well be deployed in a clustered environment. Again, file I/O is restricted in the EJB container, so this is primarily a concern for web apps. If load balancing is applied, you may not be able to guarantee that the web container that creates the file is the same one that receives the request to read the file -- it may even be on a completely different machine! Finally, there are security concerns with creating files -- how do you ensure that only the "right" users gain access to those files? It's better to store persistent data in a database, where this access can be guaranteed through J2EE mechanisms. Kyle
Howdy, Here are just a couple more... * Don't listen or accept connections on a socket. (Letting your bean become a network server completely undermines what the Container is trying to do.) * Lots of security-related things; a bean must not: -- don't access security policy information -- don't load a native library -- don't pass 'this' in or out of a method * And to add to your threads one, besides not *creating* a thread, you should not attempt to manage threads at all, including using synchronization/wait/notify, or try to change a thread's priority or name. cheers, Kathy
Kathy -- great additions, thanks! Pradeep, I would say the reasons are twofold -- (1) Laziness on the part of the container vendors. We at IBM are beat up constantly by customers that tell us "WebSphere is broken -- our program ran on (WebLogic, JBoss, etc...) but won't run on WebSphere." At which point we show them the chapter and verse of the J2EE spec, EJB Spec, or Servlet Spec that they are violating. You see, the vendors are only really motivated to support those parts of the J2EE spec that are tested by the compliance tests -- if it's not in the compliance test suite, they often ignore it... (2) Difficulty in enforcing some of the restrictions. For instance, it's easy to forbid access to a static INSIDE an EJB class -- that just requires a validator to check that the EJB implementation class has no static variables that are not final. However, it's much more challenging to determine if a class three or four levels in from an EJB call is accessing a static. Now, it's not impossible to do this -- merely very difficult. As an example, WebSphere Studio has a technology preview for a J2EE code validator that not only catches some of these "deep" J2EE violations, but also enforces best practices for J2EE development (like don't use DriverManager). Kyle [ November 25, 2003: Message edited by: Kyle Brown ]
However, it's much more challenging to determine if a class three or four levels in from an EJB call is accessing a static. Now, it's not impossible to do this -- merely very difficult.
Kyle, I was wondering the feasibility of doing exactly this (inspecting the "helper class hierarchy" for spec breakers). I ended up with the assertion that reflection is the show stopper for inspecting the helper classes. For example, the parameter for a call to Class.forName() might originate from who-knows-where and there's really no sense in testing "all class names found in the project", is there... Was my analysis correct or did I overlook something here?
It MIGHT be possible to do so with data flow analysis -- unless the value of Class.forName() is looked up from a file or database, it should be doable, but it's still quite difficult. That's why, for instance, the tool I mention for WebSphere Studio was a research project for several years before it was released. Kyle
Kyle, I have a doubt regarding your point abt ,singletons. What if i put my singleton class in the server classpath and calls it from my EJB.[Say as a startup class.Then this should be unique with in a JVM ]
Prem Kumar.k<br />Email :firstname.lastname@example.org
Joined: Aug 10, 2001
Ah, but that goes against another best practice. J2EE applications should ALWAYS be self-contained within their EAR's. Use of external classpaths should be avoided whenever possible to avoid version drift problems (in other words, I developed my application on version 1.1 of this class, but now version 1.0 is on the classpath and it breaks...) Kyle