0 Replies Latest reply on Sep 29, 2002 12:32 PM by John Snyder

    ClassNotFoundException when working with Template

    John Snyder Newbie

      Newbie here,

      I am working on a Win2K system with the jboss-3.0.0_tomcat-4.0.3 package, and am trying to build a simple test case in the Template. It seems that I am getting an incomplete .jar file, which does not contain my classes, and I would greatly appreciate any explanation of what I am doing wrong. JBoss.3.0QuickStart.Draft3.pdf says:

      "Most likely you want to add you own package structure and that is not a problem because under “/main/client”, “/main/ejb” or “/main/servlet” you can use any directory structure you like but must not add client code to another directory than “/main/client” and the same applies for EJBs and servlets."

      So, under the \main\ejb directory, I created com\pc\session\utility. In the utility directory, I have a class called SequenceGeneratorBean.java (code below). Additionally, under the \main\client directory I created com\pc, and in the pc directory I created a class called TestClient.java (code below). I modified the ant.properties file to reflect that I am using Cloudscape as my data source, and to specify the location of my servlet jar file, as follows:

      # Set the DB type mapping (Hypersonic SQL, PostgreSQL etc., see XDoclet's attribute "typemapping")
      type.mapping=Cloudscape SQL
      # Set the DataSource name your are going to use (java:/DefaultDS etc., see XDoclet's attribute "datasource")
      datasource.name=java:/CloudscapeDS
      # Uncomment this and adjust the path to point directly to JAR file containing the servlet classes
      # Attention: By uncommenting this line you start the creation of a WAR file
      servlet-lib.path=C:/Java/jboss/jboss-3.0.0_tomcat-4.0.3/server/all/lib/javax.servlet.jar

      When I ran ant, everything seemed to go OK (see ant output, below). However, in the JBoss monitor window, I got the following errors:
      ***************************
      09:50:28,323 INFO [EJBDeployer]
      Bean : com/pc/session/utility/SequenceGenerator
      Section: 22.2
      Warning: The Bean Provider must specify the fully-qualified name of the Java class that implements the enterprise bean's business methods in the <ejb-class> element.
      Info : Class not found: com.pc.session.utility.SequenceGeneratorBean

      [... ]

      09:50:28,553 ERROR [EjbModule] Initialization failed
      java.lang.ClassNotFoundException: com.pc.session.utility.SequenceGeneratorHome
      at java.net.URLClassLoader$1.run(URLClassLoader.java:198)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.net.URLClassLoader.findClass(URLClassLoader.java:186)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
      [I can provide additional tracing information and additional errors which follow, if it would be helpful.]
      ***************************

      When I ran the run-client.bat script modified to execute com.pc.TestClient, I also got "java.lang.NoClassDefFoundError: com/pc/TestClient"
      The only two jar files created when I ran ant were ejb-test.jar and web-client.war. When I un-jarred ejb-test.jar, I found none of the com.pc package anywhere.

      Obviously, I am missing something -- there must be more to coding in the template than just adding subdirectories and creating classes, but I can't seem to find any more detailed documentation. I would be very grateful for any assistance.

      Thanks,

      -- Rick

      SequenceGeneratorBean.java:
      ***************************
      package com.pc.session.utility;

      import java.rmi.*;
      import javax.ejb.*;
      import java.util.*;
      import java.sql.*;
      import javax.sql.*;
      import javax.naming.*;

      /**
      * Encapsulates the retrival of DB data
      *
      * @author John Snyder
      * @version $Revision: 1.1 $
      *
      * @ejb:bean name="com/pc/session/utility/SequenceGenerator"
      * display-name="Generates unique Identifier for an Entity"
      * type="Stateless"
      * jndi-name="ejb/com/pc/session/utility/SequenceGenerator"
      * @ejb:env-entry name="DataSource_Name"
      * value="CloudscapeDS"
      * @ejb:resource_ref res-name="jdbc/CloudscapeDS"
      */
      public class SequenceGeneratorBean implements SessionBean
      {
      // for testing
      String status = "unset";
      public String getStatus() { return status; }


      // Members
      private SessionContext context;

      // Work Methods

      /**
      * Delivers the next sequence number from the given table
      *
      * @param entityTableName Name of the table for which the next primary key is needed
      * @param pkFieldName Name of the primary key field
      *
      * @return Next sequence number
      *
      * @throws RemoteException
      *
      * @ejb:interface-method view-type="remote"
      * @ejb:transaction type="Mandatory"
      **/
      public int getNextNumber(String entityTableName, String pkFieldName) throws SQLException, NamingException
      {
      //local Connection
      Connection con = null;

      try
      {
      con = getConnection("java:/CloudscapeDS");

      int nextNumber = -1;
      String getNextNumberSQL = "SELECT max("+pkFieldName+") FROM "+entityTableName;
      Statement stmt = con.createStatement();
      ResultSet rs = stmt.executeQuery(getNextNumberSQL);
      // should always be one
      if (rs.next())
      nextNumber = 1 + rs.getInt(1);
      rs.close();
      stmt.close();

      return nextNumber;
      }
      catch (SQLException sqle)
      {throw new SQLException("Unable to generate new ID: "+sqle);}
      finally
      {
      try { con.close(); con=null; } catch (Exception ignore) {status += "\n local connection NOT closed in getNextNumber."; }
      }
      }

      // Utility Methods
      protected Connection getConnection() throws SQLException, NamingException
      {
      // default DB is Cloudscape
      return getConnection("java:/CloudscapeDS");
      }
      protected Connection getConnection(String dataSourceJndiName) throws SQLException, NamingException
      {
      // get a reference to the naming service
      InitialContext context = new InitialContext();

      // get a data source for the database
      DataSource ds = (DataSource) context.lookup(dataSourceJndiName);

      // have the datasource allocate a database connection
      return ds.getConnection();
      }

      // EJB Required Methods
      /* EJB must have public, parameterless constructor */
      public SequenceGeneratorBean() { }
      /**
      * Create the Session Bean
      *
      * @throws CreateException
      *
      * @ejb:create-method view-type="remote"
      **/
      public void ejbCreate() throws CreateException { }
      public void setSessionContext (SessionContext aContext) { context = aContext; }
      public void ejbActivate() { }
      public void ejbPassivate() { }
      public void ejbRemove() { }

      }
      ***************************

      TestClient.java:
      ***************************
      package com.pc;

      import javax.naming.InitialContext;
      import javax.rmi.PortableRemoteObject;

      import com.pc.session.utility.SequenceGenerator;
      import com.pc.session.utility.SequenceGeneratorHome;

      public class TestClient {

      public static void main(String[] args){
      try {
      InitialContext lContext = new InitialContext();

      SequenceGeneratorHome sgHome = (SequenceGeneratorHome) lContext.lookup( "ejb/com/pc/session/utility/SequenceGenerator" );
      SequenceGenerator sg = sgHome.create();
      // Get the next pk for the Person table
      int id = sg.getNextNumber("PERSON", "PERSON_ID");
      System.out.println( "Next primary key is: " + id );

      sg.remove();
      } catch( Exception e ){
      e.printStackTrace();
      }
      }

      }
      ***************************

      ant output:
      ***************************
      Buildfile: build.xml
      check-environment:
      check-jboss:
      wrong-jboss:
      check-xdoclet:
      wrong-xdoclet:
      init:
      [echo] build.compiler = ${build.compiler}
      [echo] user.home = C:\Documents and Settings\John Snyder
      [echo] java.home = C:\Java\j2sdk1.4.0_02\jre
      [echo] ant.home = C:\ant\jakarta-ant-1.5\bin\\..
      [echo] jboss.home = C:/Java/jboss/jboss-3.0.0_tomcat-4.0.3
      [echo] xdoclet.home = C:/Java/jboss/xdoclet1.1.2
      [echo] java.class.path = C:\Java\j2sdk1.4.0_02\lib\tools.jar;C:\ant\jakarta-ant-1.5\bin\\..\lib\xml-apis.jar;C:\ant\jakarta-ant-1.5\bin\\..\lib\xercesImpl.jar;C:\ant\jakarta-ant-1.5\bin\\..\lib\optional.jar;C:\ant\jakarta-ant-1.5\bin\\..\lib\ant.jar;

      xdoclet-generate:
      [ejbdoclet] Generating Javadoc
      [ejbdoclet] Javadoc execution
      [ejbdoclet] Loading source file C:\Java\jboss\template\src\main\ejb\test\session\SequenceGeneratorBean.java...
      [ejbdoclet] Loading source file C:\Java\jboss\template\src\main\ejb\test\session\TestSessionBean.java...
      [ejbdoclet] Loading source file C:\Java\jboss\template\src\main\ejb\test\message\TestMessageDrivenBean.java...
      [ejbdoclet] Loading source file C:\Java\jboss\template\src\main\ejb\test\entity\TestBMPEntityBean.java...
      [ejbdoclet] Loading source file C:\Java\jboss\template\src\main\ejb\test\entity\TestEntityBean.java...
      [ejbdoclet] Loading source file C:\Java\jboss\template\src\main\ejb\com\pc\session\utility\SequenceGeneratorBean.java...
      [ejbdoclet] Constructing Javadoc information...
      [ejbdoclet] Running
      [ejbdoclet] Running
      [ejbdoclet] Running
      [ejbdoclet] Running
      [ejbdoclet] Running
      [ejbdoclet] Running
      [ejbdoclet] Running
      [ejbdoclet] Running

      compile:
      jar:
      compile-web:
      war:
      deploy-server:
      [copy] Copying 2 files to C:\Java\jboss\jboss-3.0.0_tomcat-4.0.3\server\default\deploy
      create-client:
      [echo] JBoss Home on Unix: C:/Java/jboss/jboss-3.0.0_tomcat-4.0.3
      [echo] Java Home on Unix: C:/Java/j2sdk1.4.0_02/jre
      main:

      BUILD SUCCESSFUL
      Total time: 7 seconds