2 Replies Latest reply on Oct 9, 2004 11:41 AM by crashedsnow

    ClassNotFound errors when deploying EJB JAR (and other stori

    crashedsnow

      I am almost certain this is a total noob question, but I have run out of ideas...

      I am deploying a couple of EJBs to JBoss 3.2.5 which have several package dependencies with other libraries I have built (which have their own jar files). To keep things nice and neat, I started with creating an EAR that has everything it needs. This worked, up until one of the classes tries to access a file resource from its classpath. I am using the getResourceAsStream method of the ClassLoader to load a properties file on demand. This works EVERYWHERE except JBoss when deploying inside an EAR. In JBoss land I get a FileNotFound exception. So, to save rewriting the few thousand lines of code which rely on this feature I decided to throw neatness into the wind and deploy each JAR separately. So.. I have about 10 JAR files which consist of my own, and 3rd party libraries, and one single EJB JAR file. If I deploy all the referenced JAR files, THEN deploy the EJB jar everything works (including the getResourceAsStream BTW). However, if I restart JBoss it doesn't deploy the EJBs correctly because they reference a class in one of the other JARs which JBoss obviously hasn't loaded yet, and I get ClassNotFound errors

      Now... I am really no expert but it seems to me that JBoss is trying to load the EJBs before its loaded any of the JARs upon which my EJBs depend. Is it just me, or does this seem a little backwards?

      Anyway I am now at the point where I can't use an EAR file (which solves my ClassNotFound problems) because of the ClassLoader bugs relating to loading resources, and I can't just deploy the lot as separate JARs because JBoss can't seem to load them. Hence I'm a bit stuck.

      Tomcat (outside JBoss) doesn't seem to have any problem loading dependent jars, neither does any other app server/servlet engine I have ever used for that matter. I must be doing something wrong here. This just should work...

      Please help

        • 1. Re: ClassNotFound errors when deploying EJB JAR (and other s
          starksm64

          Dependent library jars go into the server/default/lib directory, not deploy as deploy is not a simple classpath.

          Describe the resource location of the resource you are looking for in the ear usage case and what resource name is being passed into getResourceAsStream.

          • 2. Re: ClassNotFound errors when deploying EJB JAR (and other s
            crashedsnow

            ok...

            The issue of dependent jars in server/default/lib is an ongoing point of confusion for me. The problem here is that my application may have conflicting versions of 3rd party libraries already in server/default/lib. More importantly, I may have more than one deployment which has conflicting versions of 3rd party libraries across themselves (this has been the case previously). A good example is Oracle JDBC drivers for 8i vs 9i. Same class names, different versions. If you have two apps which access two different versions of Oracle and hence need to different versions of the JDBC driver you can't just put them both in the server/default/lib path.

            So the solution to this, well, at least the solution I have previously implemented is to use EAR files with loader repositories. Pre 3.2.3 this was a bit problematic, but seems to work ok now (although I still couldn't get it to work with Oracle JDBC drivers... kept getting "apparently wrong driver"... but that's another story).

            I don't seem to be able to use EAR files here anyway because of the resource loading issue mentioned, which I shall now explain:

            I have some non-ejb classes which can dynamically load config when needed. The "convention" I have is that the config is always in the same package path as the class to whom it belongs, and it always has the same name as the FQCN of this class.

            For example:

            Given class: com.somepackage.MyClass

            I would have a config file com/somepackage/com.somepackage.MyClass.xml

            This means I can abstract out the loading of this file by assuming the convention is always true.

            When I load the file therefore, I would use a path like (actually exactly like) the one above. Thus:

             String resource = getPackagePath() + "/" + getClass().getName() + ".xml";
             InputStream in = getClass().getClassLoader().getResourceAsStream(resource);
            


            Where:

             protected String getPackagePath() {
             String pack = this.getClass().getPackage().getName();
             return pack.replaceAll("\\.", "/");
             }
            


            (ps... I am aware of the poor String concating here but it usually only happens once so I don't care)

            Now.. In EAR land, JBoss gives me an error like this:

            FileNotFoundException: file:C:/jboss-3.2.5/tmp/blahblah.ear!/com/somepackage/com.somepackage.MyClass.xml does not exist

            (NOTE: This is NOT verbatim as I don't have the actual error handy)

            It seems JBoss cannot locate the file inside the EAR. I know the path IS actually correct.

            How do I know this? I just tried a little experiment which has worked and actually solved all of my problems (although it's a bit messy)...

            I realised that one of the advantages an EAR has is the application.xml which tells it what JAR libraries to load. The absence of this was obviously why JBoss couldn't deploy my EJBs. Given that I couldn't use the EAR file, it occurred to me to "trick" JBoss into thinking it has an EAR without using one. I therefore deployed all my jars (including the ejb jar) into a sub DIRECTORY under deploy called myapp.ear. In which I created a META-INF/application.xml

            So JBoss thinks it has an EAR and looks for the application.xml. ClassNotFound issues solved. And, because it's not "actually" an EAR, the config files load fine too. (Hence I know the path for the config files is correct).

            ok... so all my problems are solved. But this seems a bit messy. I have noticed a few (couldn't find many) references to similar problems with loading resources in JAR files. Maybe this is something for the TODO list. Or maybe it's fixed in v4.x

            Any comments would be appreciated