Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>To understand why this exception has occurred, there are two things to grasp:</p> <ol> <li>How does one EJB reference another EJB</li> <li>EJB classloading</li> </ol> <p>Let's first deal with number one, so let's name first EJB (containing <code>FirstEJBRemote</code> class) <strong>EJB_A</strong> and second EJB (who tries to access EJB_A's method) <strong>EJB_B</strong>. Not going too deeply into <code>@LocalBean</code> annotations and similar stuff, the only way for EJB_B to access EJB_A's methods is through interface. In other words, EJB_A implements some interface (in your case that is <code>FirstEJBRemote</code>) which EJB_B declares and through injection retrieves an instance of EJB_A. So far, so good.</p> <p>Next, we have to understand EJB classloaders. Naturally, every external class/library that your application (in this case, EJB) uses in compile-time, has to be available also in the runtime. Otherwise, <code>ClassNotFoundException</code> will be thrown and that is exactly what happened in your case, because EJB_B is using <code>FirstEJBRemote</code> in compile-time:</p> <pre><code>private FirstEJBRemote ejb; </code></pre> <p>To provide this external class/library to the EJB in runtime, one has to do something of the following:</p> <ul> <li>Put the class/library in the lib directory of the application server</li> <li>Pack the class/library together with EJB</li> <li>Put the class/library in the classpath of EAR containing your EJB</li> </ul> <p>We will ignore third option because you said that you are not interested in EARs. Therefore, you can put <code>FirstEJBRemote</code> interface (in form of .jar file, of course) in lib directory of the Glassfish where it will be available both to EJB_A and EJB_B (thus, you don't have to pack it neither with EJB_A) or you can pack this interface together with EJB_B as well, taking care that it resides in the same package as in EJB_A.</p> <p>In your comment, you wonder why is this "complicated" procedure needed at all. The answer is quite simple - if EJB classloaders weren't isolated mutually, every class that was deployed with EJB_A will be available to EJB_B. In this particular case, that would be wished behaviour, but imagine what happens when EJB_A includes version1 of some library (logging library, for example), and EJB_B uses this same library, but version2. Both classes would be loaded and you will encounter clash everywhere, <code>ClassCastException</code> etc. (or if you are lucky, EJB_B would "only" be forced to use version1 because that class would be already loaded by classloader).</p> <p>Finally, an excerpt from <a href="http://docs.oracle.com/cd/E18930_01/html/821-2418/beadh.html#scrolltoc" rel="nofollow">Oracle GlassFish 3.1 Guide:</a></p> <blockquote> <p><strong>Circumventing Class Loader Isolation</strong></p> <p>Since each application or individually deployed module class loader universe is isolated, an application or module cannot load classes from another application or module. This prevents two similarly named classes in different applications or modules from interfering with each other.</p> </blockquote>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload