Created a class dynamically but could not use it to create typedobjects

Discussion in 'Java' started by lbrtchx@gmail.com, May 16, 2008.

  1. Guest

    I know I am pushing things a bit but I need to do things this way

    I need to create some classes (which will be mostly used as DTO and
    DAO) and I used ASM

    The thing is that then I cannot do such things as:(this is pseudo
    code I have tried many different things to no avail):

    Class K = _.getKlass();
    K0 Obj = (K0)K.newInstance

    ArrayList<K0> ALK0 = new ArrayList<K0>();
    ALK0.add(Obj);

    Even though I know he name of the class is that I created saved and
    loaded in the same context using the URLClassLoader is "K0"

    I know the created classes themselves are fine because the JVM (javap
    and java) did not complain at all and I actually used the classes by
    starting other JVM and reaching out for them

    Again I need to use the created classes to create and used typed
    objects right within the same context that they were created, without
    having to restart java

    How could you achieve such a thing, either in a plain way or hacking
    my way through?

    In case this can not be done (well, this may be why some frameworks
    such as JAXB use precompilation of type classes), please let me know
    what am I missing here

    Thanks
    lbrtchx

    Here is a short code sample of what I am trying to achieve:
    // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

    import java.util.*;
    import java.io.*;
    import java.net.*;
    import java.security.*;

    import org.objectweb.asm.*;
    import static org.objectweb.asm.Opcodes.*;

    // __
    class ASMKW02 extends ClassLoader{
    private File FlDir;
    private String aKName;
    private String[][] aFldDefs;

    // __ more sanity checks
    ASMKW02(File FlDir, String aKName, String[][] aFldDefs){
    if(!FlDir.exists()){ FlDir.mkdirs(); }
    this.FlDir = FlDir;
    this.aKName = aKName;
    this.aFldDefs = aFldDefs;
    }
    // __
    public Class getK(){
    Class K = null;

    // __
    ClassWriter KW = new ClassWriter(ClassWriter.COMPUTE_MAXS);

    // __ class def.
    KW.visit(V1_6, ACC_PUBLIC, aKName, null, "java/lang/Object", null);

    // __ default constructor
    MethodVisitor DfltCtor = KW.visitMethod(ACC_PUBLIC, "<init>", "()V",
    null, null);
    if(DfltCtor != null) {
    DfltCtor.visitCode();
    DfltCtor.visitVarInsn(ALOAD, 0);
    DfltCtor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object",
    "<init>", "()V");
    DfltCtor.visitInsn(RETURN);
    DfltCtor.visitMaxs(1, 1);
    DfltCtor.visitEnd();
    }
    // __ K Fields
    FieldVisitor FV;
    for(int i = 0; (i < aFldDefs.length); ++i){
    FV = KW.visitField(ACC_PUBLIC, aFldDefs[0], aFldDefs[1],
    null, null);
    if(FV != null){ FV.visitEnd(); }
    else{} // . . .
    }
    // __
    KW.visitEnd();

    // __
    byte[] bKAr = KW.toByteArray();

    // __ Checking if class has been already loaded by JVM . . .
    File Fl = new File(FlDir, aKName + ".class");
    try{
    ClassLoader KLCtxt =
    Thread.currentThread().getContextClassLoader();
    URL U = (Fl.toURI()).toURL();
    URLClassLoader UKL = new URLClassLoader(new URL[]{U}, KLCtxt);

    try{ K = Class.forName(aKName, true, UKL); }
    catch(ClassNotFoundException KNFX)
    { KNFX.printStackTrace(System.err); }
    if(K == null){

    // __
    K = defineClass(aKName, bKAr, 0, bKAr.length);
    if(K != null){
    System.out.println("// __ Class K: |" + K + "|");
    try{
    FileOutputStream FOS = new FileOutputStream(Fl);
    FOS.write(bKAr);
    FOS.close();
    }catch(FileNotFoundException FNFX)
    { FNFX.printStackTrace(System.err); }
    catch(IOException IOX){ IOX.printStackTrace(System.err); }
    }
    }
    }catch(MalformedURLException MFX)
    { MFX.printStackTrace(System.err); }
    // __
    return(K);
    }
    }

    // __
    public class ASMKW02Test{
    public static void main(String[] aArgs){
    // __
    String aKLoadDir = "/media/sda2/prjx/java/Ks";
    File FlDir = new File(aKLoadDir);
    // __ K Name
    String aKName = "KNm00";
    // __ K Fields
    String[][] aFldDefs = new String[][]{
    {"bByte", "B"}, // byte
    {"cChar", "C"}, // char
    {"dDouble", "D"}, // double
    {"fFloat", "F"}, // float
    {"iInt", "I"}, // int
    {"lLong", "J"}, // long
    {"sShort", "S"}, // short
    {"Is", "Z"}, // boolean
    {"aNm", "Ljava/lang/String;"},
    {"ALS", "Ljava/util/ArrayList<String>;"},
    {"HMSI", "Ljava/util/Hasmap<String, Integer>;"}
    };
    // __
    ASMKW02 ASMK = new ASMKW02(FlDir, aKName, aFldDefs);
    Class K = ASMK.getK();
    System.out.println("// __ Class K: |" + K + "|");
    try{
    K.newInstance();
    }catch(InstantiationException InstX)
    { InstX.printStackTrace(System.err); }
    catch(IllegalAccessException IlglAxX)
    { IlglAxX.printStackTrace(System.err); }
    }
    }
    // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
    , May 16, 2008
    #1
    1. Advertising

  2. On May 16, 12:41 am, wrote:
    >  I know I am pushing things a bit but I need to do things this way
    >
    >  I need to create some classes (which will be mostly used as DTO and
    > DAO) and I used ASM
    >
    >  The thing is that then I cannot do such things as:(this is pseudo
    > code I have tried many different things to no avail):
    >
    >  Class K = _.getKlass();
    >  K0 Obj = (K0)K.newInstance


    If I've read you right, the type K0 is created at runtime.

    >  ArrayList<K0> ALK0 = new ArrayList<K0>();
    >  ALK0.add(Obj);


    Generics are checked at compile time, well before K0 ever exists.

    If your generated DAOs implement a known interface that exists at
    compile time, then you can cast them to that and create a generic list
    whose type parameter is that interface, but you can't use generics
    with the actual type of a class created at runtime.

    -o
    Owen Jacobson, May 16, 2008
    #2
    1. Advertising

  3. Guest

    On May 16, 12:41 pm, Owen Jacobson <> wrote:
    > If I've read you right, the type K0 is created at runtime.


    Yes, it is

    >> ArrayList<K0> ALK0 = new ArrayList<K0>();
    >> ALK0.add(Obj);


    >Generics are checked at compile time, well before K0 ever exists.


    Well, this is what I know ;-), but I wanted to somehow find out about
    some magic trick that would let me get the structure to describe some
    entity from which I will only know at run time and then operate on it

    >If your generated DAOs implement a known interface that exists at
    >compile time, then you can cast them to that and create a generic list
    >whose type parameter is that interface, but you can't use generics
    >with the actual type of a class created at runtime.


    I will look into using a registry of interfaces then

    lbrtchx
    , May 16, 2008
    #3
  4. Guest

    I have had my second thoughts

    how does JASPER recompile a JSP, which is ultimately a sevlet/java
    class file, and updates itself when you, say include new classes to be
    used by a JSP?

    What happens when these classes include generics?

    Tomcat's main process doesn't have to be restarted, so something must
    be happening there for jasper/the servlet engine to load these new
    classes

    lbrtchx
    , May 17, 2008
    #4
  5. Arne Vajhøj Guest

    wrote:
    > I have had my second thoughts
    >
    > how does JASPER recompile a JSP, which is ultimately a sevlet/java
    > class file, and updates itself when you, say include new classes to be
    > used by a JSP?
    >
    > What happens when these classes include generics?
    >
    > Tomcat's main process doesn't have to be restarted, so something must
    > be happening there for jasper/the servlet engine to load these new
    > classes


    You can reload a class by using a new classloader (and let the
    old classloader and all objects of classes loaded by it go to GC).

    Arne
    Arne Vajhøj, May 17, 2008
    #5
  6. Guest

    On May 16, 10:35 pm, Arne Vajhøj <> wrote:
    > You can reload a class by using a new classloader (and let the
    > old classloader and all objects of classes loaded by it go to GC).

    ~
    OK, I think my seconds thoughts were not baseless, as tomcat showed
    to me generics don't appear to depend solely on compile time checks
    and/or there definitely is a way around it
    ~
    I think there should be a way to load and handle generic classes at
    run time. Tomcat does it
    ~
    This is what I did to see what was going on with tc classloaders and
    generic classes:
    ~
    1) in catalina.sh I declared: CATALINA_OPTS=-verbose:class
    ~
    2) in /webapps/ROOT/META-INF/context.xml I set: reloadable="true"
    ~
    3) then I used some test classes to play with tc loaders and see live
    how it would indeed reload changed and totally new class, even generic
    ones

    package test.k00;
    public class K00{
    public int i0;
    public long l0;
    }

    package test.k00;
    public class K02{
    public int i2;
    public String aS2;
    }

    package test.k00;
    import java.util.*;
    // __
    public class GenK00<T>{
    private String aS;
    public ArrayList<T> ALK00 = new ArrayList<T>();
    // __
    public GenK00(String aS){
    this.aS = aS;
    }
    }

    ~
    4) Inside of index.jsp I included:

    <p>
    Loading Generic classes:<br/>
    <%@page import="test.k00.*"%>

    <%
    GenK00<String> GK0 = new GenK00<String>("<String>");
    GK0.ALK00.add("blue");
    GK0.ALK00.add("rote");
    GK0.ALK00.add("blanco");

    K00 k0 = new K00();
    k0.i0 = 0;
    k0.l0 = 0L;

    K00 k1 = new K00();
    k1.i0 = 1;
    k1.l0 = 1L;

    K00 k2 = new K00();
    k2.i0 = 2;
    k2.l0 = 2L;

    GenK00<K00> GK2 = new GenK00<K00>("K00");
    GK2.ALK00.add(k0);
    GK2.ALK00.add(k1);
    GK2.ALK00.add(k2);
    GK2.ALK00.add(k1);

    K02 J = new K02();
    J.i2 = 4748;
    J.aS2 = "aS2";
    %>

    <br/>
    GK0.ALK00.size(): <%=GK0.ALK00.size()%>

    <br/>
    GK0.ALK00: <%=GK0.ALK00%>

    <br/>
    GK2.ALK00.size(): <%=GK2.ALK00.size()%>

    <br/>
    GK2.ALK00: <%=GK2.ALK00%>

    <br/>
    J: <%=J%>
    </p>

    So all that I needs to be done is look into tc classloaders

    Am I missing anything here?

    lbrtchx
    , May 23, 2008
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roxanne
    Replies:
    0
    Views:
    1,221
    Roxanne
    Jul 4, 2003
  2. =?Utf-8?B?QWxleENa?=

    aspx do not work: App-Domain could not be created

    =?Utf-8?B?QWxleENa?=, Jun 29, 2006, in forum: ASP .Net
    Replies:
    2
    Views:
    3,752
    =?Utf-8?B?UGV0ZXIgQnJvbWJlcmcgW0MjIE1WUF0=?=
    Jun 29, 2006
  3. python
    Replies:
    7
    Views:
    297
    Bruno Desthuilliers
    Jun 3, 2006
  4. msimmons
    Replies:
    0
    Views:
    460
    msimmons
    Jul 16, 2009
  5. Andy Rush
    Replies:
    0
    Views:
    137
    Andy Rush
    Jul 11, 2006
Loading...

Share This Page