Using DynamicClassLoader

To use DCL functionality:

  1. Create and configure a class loader. The code for your jConnect application should look similar to this:

    Properties props = new Properties();// URL of the server where the classes live.
    String classesUrl = "jdbc:sybase:Tds:myase:1200"; // Connection properties for connecting to above server.
    props.put("user", "grinch");
    props.put("password", "meanone");
    ... // Ask the SybDriver for a new class loader.
    DynamicClassLoader loader = driver.getClassLoader(classesUrl, props);
    
  2. Use the CLASS_LOADER connection property to make the new class loader available to the statement that executes the query. Once you create the class loader, pass it to subsequent connections as shown (continuing from the code example in step 1):

    // Stash the class loader so that other connection(s)
    // can know about it.
    props.put("CLASS_LOADER", loader);// Additional connection properties
    props.put("user", "joeuser");
    props.put("password", "joespassword");// URL of the server we now want to connect to.
    String url = "jdbc:sybase:Tds:jdbc.sybase.com:4446";// Make a connection and go.
    Connection conn = DriverManager.getConnection(url, props);
    

    Assume the Java class definition is as follows:

    class Addr {
          String street;
          String city;
          String state;
    }
    

    Assume the SQL table definition is as follows:

    create table employee (char(100) name, int empid, Addr address)
    
  3. Use the following client-side code in the absence of an Addr class in the client application CLASSPATH:

    Statement stmnt = conn.createStatement();
    
    // Retrieve some rows from the table that has a Java class
    // as one of its fields.
    
    ResultSet rs = stmnt.executeQuery(
    
          "select * from employee where empid = ’19’");
    
    if (rs.next() {
    
          // Even though the class is not in our class path,
    
          // we should be able to access its instance.
    
          Object obj = rs.getObject("address");
    
          // The class has been loaded from the server, so let's take a look.
    
          Class c = obj.getClass();
    
        // Some Java Reflection can be done here to access the fields of obj.
    
          ...
    
    }
    

The CLASS_LOADER connection property provides a convenient mechanism for sharing one class loader among several connections.

You should ensure that sharing a class loader across connections does not result in class conflicts. For example, if two different, incompatible instances of class org.foo.Bar exist in two different databases, problems can arise if you use the same loader to access both classes. The first class is loaded when examining a result set from the first connection. When it is time to examine a result set from the second connection, the class is already loaded. Consequently, the second class is never loaded, and there is no direct way for jConnect to detect this situation.

However, Java has a built-in mechanism for ensuring that the version of a class matches the version information in a deserialized object. The above situation is at least detected and reported by Java.

Classes and their instances do not need to reside in the same database or server, but there is no reason why both the loader and subsequent connections cannot refer to the same database or server.