Home

News: Does Spring violate JEE spec?

  1. Does Spring violate JEE spec? (85 messages)

    [Editor: This was originally posted in a TSS discussion forum. I'm moving it to the home page because I think it's an interesting issue for discussion.] First of all: I'm not against Spring. I've used it for several projects and I think it is a great framework. What I'd like to do is to start a discussion on some practical and also maybe more "academic" questions related to the combination Spring+JEE. These questions occured to me when I looked at the JEE specification for the first time. I always thought that would be boring ;-) but I found it pretty interesting. I already knew that you should not write directly to the filesystem. But what I did not know was that you must not use Class.forName() and similar methods in EJBs (EJB 3.0 Spec 21.1.2): "The enterprise bean must not attempt to create a class loader; obtain the current class loader; set the context class loader; set security manager; create a new security manager; stop the JVM; or change the input, output, and error streams." So here's the first violation: When I get a Spring Bean then this bean is instanciated dynamically with something like Class.forName(). Depending on the method I use this will implicitly or explicitly get a class loader. I think that it makes sense to not allow dynamic instanciation because the application server wants full control in order to optimize resource usage etc. What do you think? I'm really interested in other opinions. Maybe I got the spec wrong? A second violation I found by using the AbstractStatelessSessionBean in J2EE applications. The spec says that a Stateless Session Bean is not allowed to be a subclass of anything. Well I agree: This might be very academic but still I somehow believe that there was a reason for that. I'm also aware that I don't have to use Spring with JEE. I'm also aware of some Spring Integration Modules for different application servers that might be a better solution than using Spring "directly" (by loading e.g. Spring Context in EJB). What is your experience with such AppServer/Spring integration modules? And do you think it solves the "problems" I mentioned above. Regards Oliver

    Threaded Messages (85)

  2. Re: Does spring violate JEE spec?[ Go to top ]

    Ah, TSS. My favorite blog aggregator. It's much more convenient that javablogs.com or, god forbid, manually scouring the intarweb for such silly questions. You know what else violates the JEE spec? ASP.net. I know, I know, they're completely separate technologies but ASP.Net has the gumption to completely ignore such things as JSP and JSF in favor of its own approaches. Shameful, really.
  3. Re: Does spring violate JEE spec?[ Go to top ]

    To be more precise, Justin, it was in one of the TSS discussion forums. I've changed my ed note to better reflect that.
  4. Re: Does spring violate JEE spec?[ Go to top ]

    You know what else violates the JEE spec? ASP.net. I know, I know, they're completely separate technologies but ASP.Net has the gumption to completely ignore such things as JSP and JSF in favor of its own approaches. Shameful, really.
    Are people running ASP.Net on JEE application servers? If so that might be a problem. That aside, I think it's pretty common to violate the JEE spec in JEE applications. The limitations in the spec are stifling. It would interesting to find out if using Spring on any given JEE app-server actually results in any real problems. P.S. I attended a talk at JavaOne where a speaker warned against using Class.forName() because it had a bug or some sort of design issue. I can't remember if it was only a problem within the context of OSGi or in general. Does anyone happen to know anything about this?
  5. Are people running ASP.Net on JEE application servers? If so that might be a problem.
    I think it would be kind of a perverse accomplishment.
  6. Re: Does spring violate JEE spec?[ Go to top ]

    It was simply a joke to point out the silliness of pointing how unrelated technologies violate the tenets of other approaches. The whole question just seems mindnumbingly pointless.
  7. Re: Does spring violate JEE spec?[ Go to top ]

    It was simply a joke to point out the silliness of pointing how unrelated technologies violate the tenets of other approaches. The whole question just seems mindnumbingly pointless.
    Isn't the point that people are using Spring inside JEE containers? Am I wrong? If so, I'm completely confused by this sentence: "I'm also aware that I don't have to use Spring with JEE." Of course there's no reason to follow the JEE spec outside of JEE containers. But if you are using Spring in a JEE container, why wouldn't the JEE spec be relevant to Spring in that context?
  8. Re: Does spring violate JEE spec?[ Go to top ]

    Are people running ASP.Net on JEE application servers? If so that might be a problem.
    http://www.theserverside.com/news/thread.tss?thread_id=50450
  9. Re: Does spring violate JEE spec?[ Go to top ]

    Are people running ASP.Net on JEE application servers? If so that might be a problem.


    http://www.theserverside.com/news/thread.tss?thread_id=50450
    I was going to mention that too. I would imagine that you should, in theory, follow the spec even with something like that. All the JEE stuff I ever worked with violated the spec and the sky never came crashing down. I suppose we might have hosed the server's ability to manage it's own resources or whatever but we did these things because the app-server was dog-slow to begin with.
  10. P.S. I attended a talk at JavaOne where a speaker warned against using Class.forName() because it had a bug or some sort of design issue. I can't remember if it was only a problem within the context of OSGi or in general. Does anyone happen to know anything about this?
    I Googled "class.forname bug" and looked around a little and didn't see outstanding bugs or issues. You may be thinking of the Class.newInstance() method, which creates a new instance of a class represented by a Class object by calling its default constructor. The problem with using the newInstance() method is that a class may not have an accessible default constructor, or it may not even exist. Josh Bloch describes more of its issues at the end of Item #2 of the second edition of "Effective Java" Hope this helps. :-) Cheers, Jim
  11. P.S. I attended a talk at JavaOne where a speaker warned against using Class.forName() because it had a bug or some sort of design issue. I can't remember if it was only a problem within the context of OSGi or in general. Does anyone happen to know anything about this?


    I Googled "class.forname bug" and looked around a little and didn't see outstanding bugs or issues. You may be thinking of the Class.newInstance() method, which creates a new instance of a class represented by a Class object by calling its default constructor. The problem with using the newInstance() method is that a class may not have an accessible default constructor, or it may not even exist. Josh Bloch describes more of its issues at the end of Item #2 of the second edition of "Effective Java"

    Hope this helps. :-)

    Cheers,
    Jim
    I'm 100% sure it was about Class.forName() and now I am about 85% sure it was about classloaders. It was an OSGi talk and OSGi containers are heavily involved with classloaders. I think the point was about how to move to OSGi and his advice was to eliminate all calls to Class.forName(). I just can't remember what he suggested changing it to. Maybe it was: this.getClass().getClassLoader().loadClass() or the other version of Class.forName() I mentioned above.
  12. Re: Does spring violate JEE spec?[ Go to top ]

    P.S. I attended a talk at JavaOne where a speaker warned against using Class.forName() because it had a bug or some sort of design issue. I can't remember if it was only a problem within the context of OSGi or in general. Does anyone happen to know anything about this?
    Class.forName() may not work as you expected depending on the classloading architecture you use. In OSGi/EJB environments, containers create a somewhat complex classloader hierarchy, and not all classes are visible among modules. And this is not detailed specified by the spec. So, relying on some specific classloading strategy could hurt portability between containers.
  13. EJB3 Session Beans[ Go to top ]

    The spec says that a Stateless Session Bean is not allowed to be a subclass of anything.
    Just to clarify what the specs says: The session bean class may have superclasses and/or superinterfaces ...... A session bean class must not have a superclass that is itself a session bean class. Thanks, -Mag
  14. EJB3 Session Beans[ Go to top ]

    The spec says that a Stateless Session Bean is not allowed to be a subclass of anything.
    Just to clarify what the specs says: The session bean class may have superclasses and/or superinterfaces ...... A session bean class must not have a superclass that is itself a session bean class. Thanks, -Mag
  15. Re: EJB3 Session Beans[ Go to top ]

    The spec says that a Stateless Session Bean is not allowed to be a subclass of anything.

    Just to clarify what the specs says:
    The session bean class may have superclasses and/or superinterfaces ...... A session bean class must not have a superclass that is itself a session bean class.

    Thanks,
    -Mag
    Thanks for the clarification, but things are still a bit unclear. Could you repeat that for me? :P
  16. Re: EJB3 Session Beans[ Go to top ]

    Sorry for the repetition, it was the TSS that was misbehaving ad forced me to re-post it more than once.
  17. Re: EJB3 Session Beans[ Go to top ]

    The spec says that a Stateless Session Bean is not allowed to be a subclass of anything.

    Just to clarify what the specs says:
    The session bean class may have superclasses and/or superinterfaces ...... A session bean class must not have a superclass that is itself a session bean class.

    Thanks,
    -Mag

    Thanks for the clarification, but things are still a bit unclear. Could you repeat that for me? :P
    So you have a Session Bean- BeanA (BeanAHome BeanARemote, BeanAImpl) If yo were to write another Bean- BeanB(BeanBHome, BeanBRemote, BeanBImpl) If BeanBImpl extends BeanAImpl- you will be guilty of voilating the specs and Sun microsystems will drag you to court :)
  18. EJB, not Java EE[ Go to top ]

    Spring does violate EJB programming restrictions. So does Hibernate, and probably any framework/library that tries to be useful (and are used from inside EJBs). Many restrictions imposed by the EJB model are there for security reasons. Security agains... application developers! External 'hackers' (crackers?) won't be able to inject bytecode into the EJB container anyway (Java doesn't have buffer overflow issues C/C++ had). So, either you are in a company so big that you can't trust your own employees (how do you run a business like that?), or these restrictions are pretty useless. There are restrictions that matter, of course. Synchronization, resource access, and thread creation restrictions, all may make your applications just stop working (mostly in distributed environments). But I don't think Spring, Hibernate or any of the mainstream-enterprise-class frameworks violate them.
  19. Re: EJB, not Java EE[ Go to top ]

    Synchronization, resource access, and thread creation restrictions, all may make your applications just stop working (mostly in distributed environments). But I don't think Spring, Hibernate or any of the mainstream-enterprise-class frameworks violate them.
    To be specific: Quartz will not work properly when deployed on OC4J, so I suppose the Quartz based "Spring Scheduler" would run into the same issues. The problem is, that the Quartz worker threads are not managed by the J2EE container and the Oracle app server is using its own Thread subclass with an overridden implementation of getContextClassLoader to obtain the current class loader. So, if you initialize Quartz from a web application and make a local call to an EJB from a Quartz job, the app server does not try to switch the classloader, but executes (or tries to execute) the EJB method with the web app's classloader. This behaviour is J2EE conform, as the servlet container must only allow JNDI lookups and invokation of EJBs from threads managed by the servlet container (SRV.9.11 in the 2.4 version of the servlet spec).
  20. Re: EJB, not Java EE[ Go to top ]

    To be specific: Quartz will not work properly when deployed on OC4J, so I suppose the Quartz based "Spring Scheduler" would run into the same issues. The problem is, that the Quartz worker threads are not managed by the J2EE container and the Oracle app server is using its own Thread subclass with an overridden implementation of getContextClassLoader to obtain the current class loader. So, if you initialize Quartz from a web application and make a local call to an EJB from a Quartz job, the app server does not try to switch the classloader, but executes (or tries to execute) the EJB method with the web app's classloader.

    This behaviour is J2EE conform, as the servlet container must only allow JNDI lookups and invokation of EJBs from threads managed by the servlet container (SRV.9.11 in the 2.4 version of the servlet spec).
    I didn't mention Quartz because I thought that it wasn't usual to use it from EJBs. If it is, it would violate the EJB spec in a much more dangerous (unpredictable) way. But yes, if you create Quartz in the web container, and call EJBs from there, it will work as expected, since they'll be acquired by JNDI lookups, just like it would, if called from a Servlet, Struts Action or external client.
  21. Re: EJB, not Java EE[ Go to top ]

    <blockquoteBut yes, if you create Quartz in the web container, and call EJBs from there, it will work as expected, since they'll be acquired by JNDI lookups, just like it would, if called from a Servlet, Struts Action or external client.</blockquote> As I tried to explain, it will not, or at least it does not have to. The servlet container does not have to support JNDI lookups or EJB invokations from threads not managed by the servlet container itself. OC4J must be started with a "-userThreads" argument to allow JNDI looups from non-managed threads, but the actual EJB invokation may still fail, depending on the classloader hierarchy of the deployed applications.
  22. Re: EJB, not Java EE[ Go to top ]

    As I tried to explain, it will not, or at least it does not have to. The servlet container does not have to support JNDI lookups or EJB invokations from threads not managed by the servlet container itself. OC4J must be started with a "-userThreads" argument to allow JNDI looups from non-managed threads, but the actual EJB invokation may still fail, depending on the classloader hierarchy of the deployed applications.
    Oh, that's good to know, thanks :)
  23. In my opinion, no. While you correctly quote the EJB spec, nowhere in the J2EE spec is it mandated that you *have* to use EJB's. There's a book on my shelf that I bought in anticipation of working on a future Spring project called "J2EE(TM) Development without EJB(TM)" by Rod Johnson, the father of Spring, so that seems to be the major focus. What you omitted from the EJB spec is the rationale for your restriction: "These functions are reserved for the EJB container. Allowing the enterprise bean to use these functions could compromise security and decrease the container’s ability to properly manage the runtime environment." Since Spring is a container in its own right it's up to Spring to worry about these management issues. Just my $0.02. Thanks, Thomas
  24. In my opinion, no. While you correctly quote the EJB spec, nowhere in the J2EE spec is it mandated that you *have* to use EJB's.
    Assuming you are correct, this doesn't completely resolve the question. As I understand it the author had a specific use of Spring with EJBs that would appear to violate the spec. I think the focus on whether Spring as a whole is in violation of the JEE spec is obscuring the actual question at hand.
  25. As I understand it the author had a specific use of Spring with EJBs that would appear to violate the spec.
    I'll try again, quoting RJ: "Spring also provides *support for implementing EJBs*, in the form of convenience superclasses for EJB implementation classses, which load a Spring lightweight container based on an environment variable specified in the ejb-jar.xml deployment descriptor." So let's see what this violates: create a class loader: no obtain the current class loader: no, not the current classloader for the EJB at least set the context class loader: no either I don't think we're in violation. Thanks, Thomas
  26. obtain the current class loader: no, not the current classloader for the EJB at least
    Class.forName() calls ClassLoader.getCallerClassLoader() which gets the current class loader, does it not?
  27. Re: Does Spring violate JEE spec?[ Go to top ]

    obtain the current class loader: no, not the current classloader for the EJB at least


    Class.forName() calls ClassLoader.getCallerClassLoader() which gets the current class loader, does it not?
    We know that because we have the source code to Class.forName(). However, I haven't looked at what "new" does, but I have to imagine that it too gets the caller class loader to find the appropriate Class instance. I guess this was the point of my previous post - how can you possibly avoid using code that somewhere along the way (from the original post) "obtain[s] the current class loader"? Anyway, my feeling is that using Class.forName(String) does not violate the EJB 3.0 spec, although using Class.forName(String, boolean, ClassLoader) could violate the spec depending upon which class loader you pass in. I base my reasoning on the italicized paragraph in the EJB spec: "These functions are reserved for the EJB container. Allowing the enterprise bean to use these functions could compromise security and decrease the container’s ability to properly manage the runtime environment." I don't see that Class.forName(String) is any more dangerous for the container than "new".
  28. Re: Does Spring violate JEE spec?[ Go to top ]

    obtain the current class loader: no, not the current classloader for the EJB at least


    Class.forName() calls ClassLoader.getCallerClassLoader() which gets the current class loader, does it not?


    We know that because we have the source code to Class.forName(). However, I haven't looked at what "new" does, but I have to imagine that it too gets the caller class loader to find the appropriate Class instance. I guess this was the point of my previous post - how can you possibly avoid using code that somewhere along the way (from the original post) "obtain[s] the current class loader"?

    Anyway, my feeling is that using Class.forName(String) does not violate the EJB 3.0 spec, although using Class.forName(String, boolean, ClassLoader) could violate the spec depending upon which class loader you pass in. I base my reasoning on the italicized paragraph in the EJB spec:

    "These functions are reserved for the EJB container. Allowing the enterprise bean to use these functions
    could compromise security and decrease the container’s ability to properly manage the runtime environment."

    I don't see that Class.forName(String) is any more dangerous for the container than "new".
    It's an interesting point you make and I don't have a authoritative answer either way. But I think it's probably the case that the semantics of new and the semantics of Class.forName are not necessarily equivalent and that's the reason for the restriction.
  29. obtain the current class loader: no, not the current classloader for the EJB at least


    Class.forName() calls ClassLoader.getCallerClassLoader() which gets the current class loader, does it not?
    I think this depends on how you deploy. It can be ok for Spring to get the current class loader, but not for the EJB directly, if the class loaders are different. When I have time I'll read this: http://www.objectsource.com/j2eechapters/Ch21-ClassLoaders_and_J2EE.htm, which seems to address the issue.
  30. obtain the current class loader: no, not the current classloader for the EJB at least


    Class.forName() calls ClassLoader.getCallerClassLoader() which gets the current class loader, does it not?


    I think this depends on how you deploy. It can be ok for Spring to get the current class loader, but not for the EJB directly, if the class loaders are different. When I have time I'll read this: http://www.objectsource.com/j2eechapters/Ch21-ClassLoaders_and_J2EE.htm which seems to address the issue.
    http://www.objectsource.com/j2eechapters/Ch21-ClassLoaders_and_J2EE.htm ... sorry, the comma messed up the URL
  31. obtain the current class loader: no, not the current classloader for the EJB at least


    Class.forName() calls ClassLoader.getCallerClassLoader() which gets the current class loader, does it not?


    I think this depends on how you deploy. It can be ok for Spring to get the current class loader, but not for the EJB directly, if the class loaders are different. When I have time I'll read this: http://www.objectsource.com/j2eechapters/Ch21-ClassLoaders_and_J2EE.htm, which seems to address the issue.
    Just to be clear, I'm not convinced that it's really a problem if using Spring to for EJB violates the JEE spec. These kinds of restrictions are a big part of what I dislike about JEE. If Spring or anyone else can violate them and get away with it, more power to them, I say.
  32. Just to be clear, I'm not convinced that it's really a problem if using Spring to for EJB violates the JEE spec. These kinds of restrictions are a big part of what I dislike about JEE. If Spring or anyone else can violate them and get away with it, more power to them, I say.
    As if Spring doesn't have a bunch of restrictions itself? The main difference IMHO is that the J2EE restrictions are documented (if the developers would bother to read the documentation and learn the tools they are working with), whereas the Spring restrictions is something you more or less randomly run into, and have to spend hours with the debugger to find out why something is not working as you expected. Mixing J2EE and Spring turned out in my last project not to be the "combination of all the advantages" but a pain in the ass, having to cope with two different sets of don'ts.
  33. Just to be clear, I'm not convinced that it's really a problem if using Spring to for EJB violates the JEE spec. These kinds of restrictions are a big part of what I dislike about JEE. If Spring or anyone else can violate them and get away with it, more power to them, I say.


    As if Spring doesn't have a bunch of restrictions itself?
    Frankly, I wouldn't know. I've been meaning to evaluate Spring for a while but it just isn't a priority for me.
    The main difference IMHO is that the J2EE restrictions are documented (if the developers would bother to read the documentation and learn the tools they are working with), whereas the Spring restrictions is something you more or less randomly run into, and have to spend hours with the debugger to find out why something is not working as you expected. Mixing J2EE and Spring turned out in my last project not to be the "combination of all the advantages" but a pain in the ass, having to cope with two different sets of don'ts.
    A container should minimize the constraints on the developer, IMO. Some may be necessary but JEE's are too burdensome. Again, I don't have enough knowledge of Spring to say whether it has too many restrictions for my needs. I absolutely agree that any restrictions should be well documented.
  34. Re: Does Spring violate JEE spec?[ Go to top ]

    Class.forName() would use the thread's context classloader which would have been set by the container. If you set the context classloader yourself (provided your security manager allows this) to do something special and then forget it to reset it to the original context classloader on the thread then you might shoot yourself in the foot. The whole point of these restrictions is if you want to play with them you better know what you're doing and I'd expect the Spring guys to know what they're doing.
  35. Class.forName() would use the thread's context classloader which would have been set by the container.
    No, it would not, at least not if the implementation complies with the API docs. Class.forName(String) uses the current class' classloader, so if used from a non-static context, the following two statements are identical: Class.forName(className); Class.forName(className, true, getClass().getClassLoader()); According to "The Java Virtual Machine Specification", chapter 5.3, the Java VM should use the same behaviour when loading classes, so if I'm not missing something important, "Class.forName("A").newInstance()" and "new A()" should always be equivalent, also in a J2EE environment.
  36. Maybe this helps: http://blog.bjhargrave.com/2007_07_01_archive.html
  37. Class.forName() caching[ Go to top ]

    The problem with Class.forName() is that it has the side effect of caching the results. In some environments, the same classname may exist multiple times, such as in an OSGi environment. This means that your second call to Class.forName could actually return a Class that is not visible to the classloader doing the call. Instead, you should load classes using classloader.loadClass() .
  38. Re: Class.forName() caching[ Go to top ]

    The problem with Class.forName() is that it has the side effect of caching the results. In some environments, the same classname may exist multiple times, such as in an OSGi environment.

    This means that your second call to Class.forName could actually return a Class that is not visible to the classloader doing the call.

    Instead, you should load classes using classloader.loadClass() .
    Can you point me to something that I could read for a more in-depth understanding of this? Thanks.
  39. Re: Class.forName() caching[ Go to top ]

    The problem with Class.forName() is that it has the side effect of caching the results. In some environments, the same classname may exist multiple times, such as in an OSGi environment.

    This means that your second call to Class.forName could actually return a Class that is not visible to the classloader doing the call.

    Instead, you should load classes using classloader.loadClass() .


    Can you point me to something that I could read for a more in-depth understanding of this?

    Thanks.
    Sure. I found a nice article here: http://blog.bjhargrave.com/2007/09/classforname-caches-defined-class-in.html
  40. Geez this thread is pointless. We all know Spring is ok, and Spring AS is failure. Next please.
  41. Re: Class.forName() caching[ Go to top ]

    The problem with Class.forName() is that it has the side effect of caching the results. In some environments, the same classname may exist multiple times, such as in an OSGi environment.

    This means that your second call to Class.forName could actually return a Class that is not visible to the classloader doing the call.

    Instead, you should load classes using classloader.loadClass() .


    Can you point me to something that I could read for a more in-depth understanding of this?

    Thanks.


    Sure. I found a nice article here: http://blog.bjhargrave.com/2007/09/classforname-caches-defined-class-in.html
    I guess the remaining question here is whether this caching behavior of Class.forName() is consistent with new or not.
  42. I never said they'd be different - yes, Class.forName("A").newInstance() and new A() should be equivalent because, by default, the thread that calls them would use the same context classloader, unless you've mucked around with the thread's context classloader yourself. When your app is running in an app server env, the threads that get handed out of the pool would have their context classloaders set appropriately so that the container and the application code can load appropriate classes. You are treading the edge if you change that context classloader - not necessarily the wrong thing to do but you gotta know what you're doing.
  43. Re: Does Spring violate JEE spec?[ Go to top ]

    I never said they'd be different - yes, Class.forName("A").newInstance() and new A() should be equivalent because, by default, the thread that calls them would use the same context classloader, unless you've mucked around with the thread's context classloader yourself. When your app is running in an app server env, the threads that get handed out of the pool would have their context classloaders set appropriately so that the container and the application code can load appropriate classes. You are treading the edge if you change that context classloader - not necessarily the wrong thing to do but you gotta know what you're doing.
    Isn't this at least part of the point of the restriction? In a app server environment you'd also need to know what the container is doing, right?
  44. I never said they'd be different - yes, Class.forName("A").newInstance() and new A() should be equivalent because, by default, the thread that calls them would use the same context classloader, unless you've mucked around with the thread's context classloader yourself.
    But as I wrote, according to the API and VM specification, neither would use the threads context classloader. They are using the classloader used to previously load the class, from which the method/constructor is invoked.
  45. They are using the classloader used to previously load the class, from which the method/constructor is invoked.
    Unless I'm misunderstanding, that's completely different from what "new A()" does.
  46. They are using the classloader used to previously load the class, from which the method/constructor is invoked.


    Unless I'm misunderstanding, that's completely different from what "new A()" does.
    What do you think "new A()" does and why? It is specified in "The Java Virtual Machine Specification", chapter 5.3. If a class or interface D references a class or interface C with the name N and N is is not an array, then: "If D was defined by the bootstrap class loader, then the bootstrap class loader initiates loading of C (§5.3.1). If D was defined by a user-defined class loader, then that same user-defined class loader initiates loading of C (§5.3.2)."
  47. They are using the classloader used to previously load the class, from which the method/constructor is invoked.


    Unless I'm misunderstanding, that's completely different from what "new A()" does.


    What do you think "new A()" does and why?
    new A() doesn't necessarily load from the same class loader that was previously used for that class. For example, if you have sibling classloaders where their parent doesn't provide the class or if you've turned off the inverted class loading in one of your web apps. I know this because I've spent many an hour dealing with issues in app servers resulting from this behavior. It's possible I might just be misunderstanding what you wrote or that you glossed over the details.
  48. new A() doesn't necessarily load from the same class loader that was previously used for that class.
    Depending on what you mean with "that" class, it does, if your VM complies to the specification. But I can always try to explain it even more detailed. Let's assume we have something like this: public class A { public A() { new B(); } } As soon as you somehow load class A (you don't have to instantiate it), the VM will also load class B, since it is referred by class A. To load class B, the VM will ask the classloader which defines class A to also load class B. If class A is defined by a classloader with parents or siblings, depending on the implementation, A's classloader may of course ask its parents and/or siblings to resolve class B, so that B later is not necessarily defined by the same classload as A (using the meaning of "load" and "define" as explained in the VM spec). Let's assume that I change the implementation of A to: public class A { public A() { Class.forName("B"); } } Now, the VM is not trying to load class B, until I create an instance of A, but the Class.forName method should use exactly the same strategy as in the previous example to load class B. If you still think I'm wrong, I would be very happy if you would point to a legitimate source for your claim.
  49. If class A is defined by a classloader with parents or siblings, depending on the implementation, A's classloader may of course ask its parents and/or siblings to resolve class B, so that B later is not necessarily defined by the same classload as A
    I'm not sure why you are involving two classes in this and classloaders don't (normally) load classes from siblings. They load classes from their parents in standard approach. What I am really unsure of is whether you are claiming that once a class A is loaded anywhere in the JVM, new A() will always resolve to that same class.
  50. What I am really unsure of is whether you are claiming that once a class A is loaded anywhere in the JVM, new A() will always resolve to that same class.
    Is it really so difficult to understand what I'm writing? I must have written at least three times, that when the VM loads a class D, because it is referenced by a class C (e.g. with "new D()"), the VM uses the classloader, which defines C to load D. Isn't it then obvious, that if class B is defined by a different classloader than C and you try a "new D()" from B as well, that the D instance in B may be (but does not have to be) of a different type than the D instance in C? If you e.g. deploy classes (A and D), (B and D) and (C and D) as three independent J2EE apps, none of the classes are provided by the app server through a parent classloader and the appserver complies to the J2EE classloader spec, you will see D defined by three different classloaders in A, B and C. If D is provided from the app server classloader, e.g. as part of a common library and not deployed as part of the J2EE apps, A, B and C will (most likely) see the same type of D. If you use Class.forName("D") from A, B and C to load D, you will see exactly the same behaviour.
  51. What I am really unsure of is whether you are claiming that once a class A is loaded anywhere in the JVM, new A() will always resolve to that same class.


    Is it really so difficult to understand what I'm writing? I must have written at least three times, that when the VM loads a class D, because it is referenced by a class C (e.g. with "new D()"), the VM uses the classloader, which defines C to load D. Isn't it then obvious, that if class B is defined by a different classloader than C and you try a "new D()" from B as well, that the D instance in B may be (but does not have to be) of a different type than the D instance in C?
    I understand that but it wasn't clear to me from what you were writing that you did. It's hard to know when you talk about a class whether you mean the resolved definition in a classloader or the more general conceptual class. Now that I understand exactly what you mean, we can have a more meaningful conversation. Please don't take it as on offense that I misunderstood you.
    If you use Class.forName("D") from A, B and C to load D, you will see exactly the same behaviour.
    I've been reading some stuff and I might have an idea how it might differ but I need to test it out. What you are saying makes sense to me but I'm reading things that suggest it works otherwise.
  52. Sorry, you're right - wrote too quickly without thinking. Class.forName() will always use the classloader that loaded the caller class which may or may not be the same as the calling thread's context classloader. So, if for some weird reason, you've gone from your EJB/servlet code to a class on the system classpath and then do a class.forName() to load a class in the jar/war it'd fail, unless you use the thread's ctx classloader to load that class.
  53. In my opinion, no. While you correctly quote the EJB spec, nowhere in the J2EE spec is it mandated that you *have* to use EJB's.


    Assuming you are correct, this doesn't completely resolve the question. As I understand it the author had a specific use of Spring with EJBs that would appear to violate the spec. I think the focus on whether Spring as a whole is in violation of the JEE spec is obscuring the actual question at hand.
    Why "violate EJB spec" == "violate JEE spec"? Are we still debating "JEE == EJB"?
  54. In my opinion, no. While you correctly quote the EJB spec, nowhere in the J2EE spec is it mandated that you *have* to use EJB's.


    Assuming you are correct, this doesn't completely resolve the question. As I understand it the author had a specific use of Spring with EJBs that would appear to violate the spec. I think the focus on whether Spring as a whole is in violation of the JEE spec is obscuring the actual question at hand.


    Why "violate EJB spec" == "violate JEE spec"? Are we still debating "JEE == EJB"?
    No. I was just pointing out that even though the terminology was imprecise or even incorrect, there was still a valid question to be discussed.
  55. Class.forName()?[ Go to top ]

    I don't understand the Class.forName() issue. How are these really different? Class clazz = Class.forName("java.lang.Object"); Object o = clazz.newInstance(); --- Object o = new Object(); Surely they both use a classloader to load the bytecode? Is there something I am missing?
  56. Re: Class.forName()?[ Go to top ]

    By using the Reflection API, you can access classes and members (attributes, methods) that wouldn't be accessible otherwise (private visibility, for example). This would be a security issue, according to the spec.
  57. Re: Class.forName()?[ Go to top ]

    By using the Reflection API, you can access classes and members (attributes, methods) that wouldn't be accessible otherwise (private visibility, for example). This would be a security issue, according to the spec.
    You don't need to use Class.forName to do that. getClass() can be called on any Object.
  58. Re: Class.forName()?[ Go to top ]

    By using the Reflection API, you can access classes and members (attributes, methods) that wouldn't be accessible otherwise (private visibility, for example). This would be a security issue, according to the spec.


    You don't need to use Class.forName to do that. getClass() can be called on any Object.
    The Reflection API is not just Class.forName(). All classes from java.lang.reflect (Class, Method, Field, Array, etc.) are part of it. The restriction in the EJB spec is on the Reflection API, not just Class.forName().
  59. Re: Class.forName()?[ Go to top ]

    By using the Reflection API, you can access classes and members (attributes, methods) that wouldn't be accessible otherwise (private visibility, for example). This would be a security issue, according to the spec.


    You don't need to use Class.forName to do that. getClass() can be called on any Object.


    The Reflection API is not just Class.forName(). All classes from java.lang.reflect (Class, Method, Field, Array, etc.) are part of it. The restriction in the EJB spec is on the Reflection API, not just Class.forName().
    Yeah but the spec just says don't call Class.forName() right? And Like I said, you can get a reference to a Class object without call Class.forName().
  60. Re: Class.forName()?[ Go to top ]

    Yeah but the spec just says don't call Class.forName() right? And Like I said, you can get a reference to a Class object without call Class.forName().
    Or more correctly, it says basically not to mess with ClassLoaders.
  61. Re: Class.forName()?[ Go to top ]

    Yeah but the spec just says don't call Class.forName() right? And Like I said, you can get a reference to a Class object without call Class.forName().
    From the spec: "The enterprise bean must not attempt to query a class to obtain information about the declared members that are not otherwise accessible to the enterprise bean because of the security rules of the Java language. The enterprise bean must not attempt to use the Reflection API to access information that the security rules of the Java programming language make unavailable."
  62. Re: Class.forName()?[ Go to top ]

    Oh, and there is no mention of Class.forName() in the text of the spec.
  63. Re: Class.forName()?[ Go to top ]

    Yeah but the spec just says don't call Class.forName() right? And Like I said, you can get a reference to a Class object without call Class.forName().


    From the spec:
    "The enterprise bean must not attempt to query a class to obtain information about the declared members that are not otherwise accessible to the enterprise bean because of the security rules of the Java language. The enterprise bean must not attempt to use the Reflection API to access information that the security rules of the Java programming language make unavailable."
    That's all well and good but that's not the only reason the spec says not to use Class.forName() or similar features. Like you already pointed out yourself, there are two distinct issues at hand. Complex classloader implementations and security.
  64. Re: Class.forName()?[ Go to top ]

    That's all well and good but that's not the only reason the spec says not to use Class.forName() or similar features. Like you already pointed out yourself, there are two distinct issues at hand. Complex classloader implementations and security.
    Yes, both are issues, but security is not a really valid one in most cases (UMHO), and classloader visibility is a consideration you have to make when developing/packaging your app, but not really an impediment, as messing with Threads is. But still a violation, of course.
  65. Re: Class.forName()?[ Go to top ]

    I don't understand the Class.forName() issue. How are these really different?

    Class clazz = Class.forName("java.lang.Object");
    Object o = clazz.newInstance();
    ---
    Object o = new Object();

    Surely they both use a classloader to load the bytecode?

    Is there something I am missing?
    I think the issue might be what classloader is used by Class.forName(String). Come to think of it, that might be the issue I mentioned above that I'm trying to recall. I wonder if it's OK to use: forName(String name, boolean initialize, ClassLoader loader) With the appropriate classloader.
  66. Re: Class.forName()?[ Go to top ]

    I wonder if it's OK to use:

    forName(String name, boolean initialize, ClassLoader loader)

    With the appropriate classloader.
    I think I answered my own question and the answer is no.
  67. Re: Class.forName()?[ Go to top ]

    Just look at the code. Class.forName(String) delegates to Class.forName(String, boolean, ClassLoader)
  68. Re: Does Spring violate JEE spec?[ Go to top ]

    I already knew that you should not write directly to the filesystem.
    does that mean i should not use logging framework which writes to file .
  69. Re: Does Spring violate JEE spec?[ Go to top ]

    I already knew that you should not write directly to the filesystem.

    does that mean i should not use logging framework which writes to file .
    Most enterprise Java applications should use log4j, a logging framework that writes to files. Not only does log4j write to the file system it also creates threads to monitor the config file and to support the asynch loggers. This also violates the EJB spec. There is no good way to do many of the things enterprise developers generally need to do inside of the EJB spec. My reaction learning about EJB in 1999 was "How can EJB fulfil these promises?" Alot less than nine years later it was clear that EJB has failed to deliver on the promises made for it and that it should be avoided in general. EJB is a lesson to us all that others don't always know better.
  70. Agree and disagree[ Go to top ]

    I already knew that you should not write directly to the filesystem.

    does that mean i should not use logging framework which writes to file .


    Most enterprise Java applications should use log4j, a logging framework that writes to files.

    Not only does log4j write to the file system it also creates threads to monitor the config file and to support the asynch loggers. This also violates the EJB spec.

    There is no good way to do many of the things enterprise developers generally need to do inside of the EJB spec.

    My reaction learning about EJB in 1999 was "How can EJB fulfil these promises?" Alot less than nine years later it was clear that EJB has failed to deliver on the promises made for it and that it should be avoided in general.

    EJB is a lesson to us all that others don't always know better.
    I've gotta agree and disagree. I agree on your conclusion that others don't always know better. I'd disagree that there is no good way to do many of the things enterprise developers generally need to do inside of the EJB spec. To some extent. First off, as I said in the post above yours, JEE is not only about EJB. If enterprise developers only limit themselves to EJB, then they are not enterprise developers, they are EJB developers and will not get far. The other components/system/tomato/tomaeto within JEE has different restrictions, some more relaxed and if you feel the need to be 100% compliant, which I personally wouldnt bother, you can do it outside of the EJB container, thus not violating the spec. In your example of log4j. A lot of enterprise level apps use asynchronous logging where they dont write to file sychronously, the log message gets dispatched to a jms queue via an asycn log4j appender. If you are really strict on compliance you can then have a standalone jms client java app reading from the queue and writing to log files outside of the JEE container. You can also disable the monitoring thread for config changes, in Prod we wouldnt change stuff dynamically anyway, well at least for me. The point is, there are many valid ways to do things without violating the spec. Just because you havent found one, does not mean it cannot be done. Dont fall into the boolean thinking mental pit of can/yes and cannot/no when there is also the other possibility of you dont know. And enterprise/JEE is not EJB, EJB is merely a subset, its restrictions should not mean the same applies to JEE as a whole. And just because the EJB spec prohibits you to do something within the EJB container, does not mean you cannot externalize the work into other parts of the JEE container and feed the result back to your EJB.
  71. Re: Agree and disagree[ Go to top ]

    In your example of log4j. A lot of enterprise level apps use asynchronous logging where they dont write to file sychronously, the log message gets dispatched to a jms queue via an asycn log4j appender. If you are really strict on compliance you can then have a standalone jms client java app reading from the queue and writing to log files outside of the JEE container.
    You can do that, but it's not what I would suggest if you asked me how to do asynchronous logging from an EJB.
    You can also disable the monitoring thread for config changes, in Prod we wouldnt change stuff dynamically anyway, well at least for me. The point is, there are many valid ways to do things without violating the spec. Just because you havent found one, does not mean it cannot be done.
    There are creative ways to deal with the limitations of EJB. Some of them might even be good. Finding them is not the best use of time.
  72. Re: Does Spring violate JEE spec?[ Go to top ]

    I already knew that you should not write directly to the filesystem.

    does that mean i should not use logging framework which writes to file .


    Most enterprise Java applications should use log4j, a logging framework that writes to files.

    Not only does log4j write to the file system it also creates threads to monitor the config file and to support the asynch loggers. This also violates the EJB spec.

    There is no good way to do many of the things enterprise developers generally need to do inside of the EJB spec.

    My reaction learning about EJB in 1999 was "How can EJB fulfil these promises?" Alot less than nine years later it was clear that EJB has failed to deliver on the promises made for it and that it should be avoided in general.

    EJB is a lesson to us all that others don't always know better.
    I agree completely at a conceptual level but I would refine it a little. The thing that has always bothered me about EJB (and any number of other 'trust the vendor' tools) wasn't so much that they limit what you can do in certain contexts but that they don't provide a clean way to modify and extend that context so that you can solve your own problems. "others don't always know better" is a good way to say how I feel about this. I've been left high-and-dry by vendors too many times to feel comfortable placing all my eggs in their basket without any contingency plans that can be quickly implemented.
  73. Re: Does Spring violate JEE spec?[ Go to top ]

    I agree completely at a conceptual level but I would refine it a little. The thing that has always bothered me about EJB (and any number of other 'trust the vendor' tools) wasn't so much that they limit what you can do in certain contexts but that they don't provide a clean way to modify and extend that context so that you can solve your own problems. "others don't always know better" is a good way to say how I feel about this. I've been left high-and-dry by vendors too many times to feel comfortable placing all my eggs in their basket without any contingency plans that can be quickly implemented.
    Repeating two perspectives on this I have heard lately, one, that the divide between the framework/DSL (Domain Specific Language) provider and the user is bug not a feature, two, that components/libraries are much easier to design and evolve than frameworks/DSL's.
  74. Re: Does Spring violate JEE spec?[ Go to top ]

    Repeating two perspectives on this I have heard lately, one, that the divide between the framework/DSL (Domain Specific Language) provider and the user is bug not a feature, two, that components/libraries are much easier to design and evolve than frameworks/DSL's.
    I actually think that frameworks and DSL have an important role to play in modern development. The problem begins when the framework or DSL provider makes the decides that all problems that cannot be solved within the framework will be solved by the provider only. My problem with EJB is not that it's a framework but that it lacks powerful mechanisms for extension. A constrained approach can be useful as long as it's not the only approach available. The time lost trying to solve problems with inadequate tools more than eliminates the time saved with such frameworks in my experience.
  75. I don't know that I care.[ Go to top ]

    Prior to Spring, to get pluggable component flexibility in my apps, I would frequently create a factory class that would dynamically load beans (using class.forName read from a properties file). Did that violate the spec - probably ... but flexibility (and refactorability) is more important to me than adherence to the spec. Also comparing Spring to EJB is an apples to oranges comparison to some degree b/c Spring offers a good bit more than just an app context (e.g. MVC, and so many integration points w/ other technologies). I know EJB development has gotten a lot better but from an efficiency perspective, I doubt seriously they are easier than POJO based beans and they simply add a layer of complexity for the sake of scalability, which can be achieved by other less complex means. ... FWIW :-)
  76. Topic starter is confused[ Go to top ]

    JEE spec is not EJB Spec. EJB Spec is one of the many specs for various technologies that make up JEE. Similarly, a JEE server runs various sub-containers for each of these technologies. I believe the poster's question, hence a correction to the topic title, should be Does Spring violate the EJB Spec. Yes you can argue, that violating the EJB spec is violating JEE spec, but not everyone that uses JEE uses EJB. Btw, the specs for other technologies in JEE may be a bit more relaxed compared to the EJB spec for some stuff. In that case, if you are a person that is anal about spec violation, you might want to bootstrap such process that violate the EJB spec into the other containers within the JEE server and make that available. Personally I really wouldnt bother.
  77. Wouldn't be more proper to say: Does Spring rapes JEE spec?
  78. Evolution[ Go to top ]

    I think rules are valuable until we don’t have to break them. After it we need new rules which are responsible to our needs. After a while new rules will be some old conventions. What is J2EE? It contains some tools which developed based on rules and conventions and not more. It is only a sign of evolution.
  79. Wouldn't be more proper to say:

    Does Spring rapes JEE spec?
    No. Should be "Does Spring rape EJB spec?
  80. Wouldn't be more proper to say:

    Does Spring rapes JEE spec?


    No. Should be "Does Spring rape EJB spec?
    Better yet, "Does Spring rape the EJB spec"?
  81. Does Spring violate JEE spec?[ Go to top ]

    But what I did not know was that you must not use Class.forName() and similar methods in EJBs (EJB 3.0 Spec 21.1.2):

    "The enterprise bean must not attempt to create a class loader; obtain the current class loader;
    set the context class loader; set security manager; create a new security manager; stop the
    JVM; or change the input, output, and error streams."

    The snippet below from "http://java.sun.com/blueprints/qanda/ejb_tier/restrictions.html" might help. Why is there a restriction against using the Java Reflection APIs to obtain declared member information that the Java language security rules would not allow? Doesn't Java automatically enforce those rules? Contrary to common belief, most of the Java Reflection API can be used from EJB components. For example, loadClass() and invoke() can both be used by enterprise beans. Only certain reflection methods are forbidden. This restriction refers to the enabling of the security permission ReflectPermission. The suppressAccessChecks permission target name, when enabled, allows a class to use reflection to inspect, access, and modify protected and private members and methods in other classes. Obviously, if EJB components are using private or protected members or methods to manage sensitive information, this facility could be used to violate security mechanisms. Therefore, the EJB specification explicitly restricts usage of suppressAccessChecks, to prevent the security hole that would result. Denial of ReflectPermission is part of the standard security policy for an EJB container. Why all the restrictions on creating class loaders and redirection of input, output, and error streams? Class loading is allowed, but creating custom loaders is not, for security reasons. These restrictions exist because the EJB container has responsibility for class loading and I/O control. Allowing the EJB to perform these functions would interfere with proper operation of the Container, and are a security hazard. The Java Pet Store has code that loads classes from inside an enterprise bean class using Class.forName(), in StateMachine.
  82. Does Spring violate JEE spec?[ Go to top ]

    The most complete lightweight container. Spring scaled up for deployment in any environment (J2SE or J2EE).
  83. As I read this post yesterday (without any comments) I asked myself I there would be some people having enough time to investigate - to write really useful and profounded answers. But all I found this morning is a boring and useless discussion about classloaders and what somebody could have heard about it in the context of OSGi... WOW!
  84. As I read this post yesterday (without any comments) I asked myself I there would be some people having enough time to investigate - to write really useful and profounded answers. But all I found this morning is a boring and useless discussion about classloaders and what somebody could have heard about it in the context of OSGi... WOW!
    Does it occur to you at all that it's really stupid to post things like this? Is this really all you have to contribute? And, you almost seem proud of this uselessness.
  85. Does Spring violate JEE spec?[ Go to top ]

    Yes. Moving on ...
  86. Re: Spring jobs claims[ Go to top ]

    Wow, big transition from the claims on TSS to a full-fledged press release: http://www.springsource.com/node/521 Rod, you have my friend Solomon Duskis to thank for that release, and yet, i still don't understand why you continue the general banter about "over-taking" and "legacy" EJB... It is defensive posturing and is not reflected in the customers you are trying to work within, you will not start a revolution and get everyone to ditch app servers, you just need to integrate with them... I am all for Spring, and I give SpringSource props for the past year, but this is a staid analysis of momentum and actual implementations, surely, you guys can do better than that...