-
1. Re: inserting duplicated members
chiba May 18, 2004 4:46 AM (in response to fluca1978)I have just released 3.0 beta!
This version rejects such a duplicated member.
In principle, you can add a duplicated member to
a class file but the JVM will reject that class file
since it does not pass bytecode verification. -
2. Re: inserting duplicated members
fluca1978 May 18, 2004 7:19 AM (in response to fluca1978)Maybe I'm misunderstanding but I've the following code to work on my system:
CtField fields[]=src.getDeclaredFields();
CtField addingField=null;
for(int i=0;i<fields.length;i++) {
addingField=new CtField(fields.getType(),fields.getName(),dest);
addingField.setModifiers(fields.getModifiers());
dest.addField(addingField);
}
supposing src and dest are CtClass objects. Now what I cannot understand is why the system is allowing me to copy (and create) objects from the dest class even if the I copy duplicated fields (I mean fields with the same name but different type) from src to dest. Moreover, if I try something similar with methods:
CtMethod toAdd[]=src.getDeclaredMethods();
CtMethod copy=null;
for(int i=0;i<toAdd.length;i++) {
copy=CtNewMethod.copy(toAdd,dest,null);
dest.addMethod(copy);
}
and the method has the same signature of another one, which already exists in src, I got an ClassFormatException during creation. Why this does not happen with the fields?
Hope someone can explain me this.
Luca -
3. Re: inserting duplicated members
chiba May 19, 2004 8:09 AM (in response to fluca1978)Are src and dest different CtClass objects?
If yes, the problem is not adding copied
methods. I think maybe your way of using a
class loader is somewhat wrong. Can you show
me the code that throws ClassFormatError? -
4. Re: inserting duplicated members
fluca1978 May 20, 2004 6:37 AM (in response to fluca1978)Well, src and dest are different CtClass, I mean they are produced from different classes. When I try to define the class, in my classloader, as:
/* create the pools */
ClassPool aPool=ClassPool.getDefault();
this.addClasspathToPoll(aPool);
.....
byte[] code= aPool.write(className);
return this.defineClass(className,code,0,code.length);
I got the exception, if the code produced by the pool is related to a class manipulate with two method with the same signature. Is the above the code you were looking for?
Thanks,
Luca -
5. Re: inserting duplicated members
chiba May 20, 2004 9:51 AM (in response to fluca1978)Here is my thought.
The JVM throws an exception if a class has two
methods with the same name and signature
becuase such a class cannot pass the bytecode
verification. This is the spec.
I guess the reason that the JVM accepts a class
that has two fields with the same name is because
the JVM wrongly ignore such duplicated fields,
i.e. this is a bug of the JVM.
I don't know. Anyway, if you use Javassist 3.0,
Javassist does not allow you to create such
borken classes!
Please try it. -
6. Re: inserting duplicated members
fluca1978 May 21, 2004 8:18 AM (in response to fluca1978)Dear Chiba,
I'll try it with javassist 3 next week and I will post results. Nevertheless I'm running the posted code oisver jvm 1.4.1 and 1.4.2, thus I don't believe that duplicated fields are due to a bug.
What I'd like to understand is how javassist adds a new field. I read an old article from Gosling, "Oak Intermediate bytecode" (ACM SIGPLAN workshop 95) where it talks about the Oak/Java method to access variables. Supposing it is still valid, variables are not accessed thru an offset but trhu a two level offset: first the symbol table is queried and then the access is done at the offset contained in the symbolic table for the specified variable. This means that duplicated variables can exists in a class file, since it suffices to use different symbolic table entries and offsets. This is the theory. As you stated, the bytecode verifier should check for this, but if the bytecode has been rightly produced, thus variable are not considered as duplicated but as different variables with the same name, it has no chance to find it out!
Now hod does javassit add a new ctfield? I believe it appends a new entry to what will be the symbolic table, isn't it? Can you explain me?
Thanks,
Luca -
7. Re: inserting duplicated members
chiba May 23, 2004 11:42 AM (in response to fluca1978)Yes, a field is identified by a pair of name and type
at the bytecode level.
BTW, I found the answer. The JVM Spec book says in Sec 4.5:
Each field is described by a field_info structure. No two fields in one class file may have the same name and descriptor.
So at the bytecode level, two fields can share the same name if their types are different. I didn't
know this fact. :< -
8. Re: inserting duplicated members
fluca1978 May 24, 2004 2:32 AM (in response to fluca1978)Well, I suppose it suffices the field_info is different, since even adding fields of the same type works. I've tried it both with a primitice type (an int) and an object (a string), both with the same name and the same access specifier (even if this should not change things) and it works.
Luca -
9. Re: inserting duplicated members
fluca1978 May 31, 2004 8:22 AM (in response to fluca1978)I've tested javassist 3 (beta), recompiling my sources with the above library, but the behavior of the shown code has not changed. I've substituted the aPool.write() call with a call toBytecode() over the CtClass object, but I'm still able to copy duplicated members as detailed in previous posts.
Any idea?
Thanks,
Luca