Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / January 2006

Tip: Looking for answers? Try searching our database.

loading class with a different name

Thread view: 
Francesco Devittori - 13 Jan 2006 16:46 GMT
Hi all,
I want to write a specialized classLoader that loads a class under a
different name.

For example, it should load the bytecode of "java.util.ArrayList" and
provide the class MyArrayList instead of ArrayList. The bytecode of
MyArrayList should be the same as the one of ArrayList (i.e. objects of
the two classes work the same way).
That way I could end up with objects of type ArrayList and objects of
MyArrayList, which work the same way but are not "compatible".

Do someone with some experience with classLoaders thinks this is
possible? If yes, how difficult would it be?

TIA,
Francesco
Stefan Ram - 13 Jan 2006 17:06 GMT
>Do someone with some experience with classLoaders thinks this
>is possible? If yes, how difficult would it be?

 I have nearly no knowledge about class loaders and nearly no
 experience with tem, but recently I hacked together something
 like this. - Not exactly the same as you require: It does
 not use two names, but two class loaders.

 Beware! The following example does not follow style rules for
 writing good class loaders!

 I wanted to show how to create two "instances" of a class with
 static entries:

public class Scan { static int i = 0; public static int get(){ return i++; }}

 So here I go, creating two "instances":

public class Main
{ public static void main( java.lang.String[] args ) throws java.lang.Exception
 { final java.lang.Class instance1 = new ScanLoader().loadClass( "Scan" );
   final java.lang.Class instance2 = new ScanLoader().loadClass( "Scan" );
   final java.lang.Class[] c = new java.lang.Class[]{};
   final java.lang.Object[] o = new java.lang.Object[]{};
   java.lang.System.out.println( instance1.getMethod( "get", c ).invoke( null, o ));
   java.lang.System.out.println( instance1.getMethod( "get", c ).invoke( null, o ));
   java.lang.System.out.println( instance2.getMethod( "get", c ).invoke( null, o ));
   java.lang.System.out.println( instance2.getMethod( "get", c ).invoke( null, o )); }}

 They can count indepently of each other, as the
 output shows:

0
1
0
1

 And here is my custom class loader hack:

class ScanLoader extends ClassLoader
{ public ScanLoader()
 { super( ScanLoader.class.getClassLoader() ); }
 public java.lang.Class<?> loadClass( final java.lang.String className )
 throws ClassNotFoundException
 { return findClass( className ); }
 public java.lang.Class<?> findClass( final java.lang.String className )
 { byte classByte[];
   java.lang.Class<?> result = null;
   if( "java.lang.Object".equals( className ))return java.lang.Object.class;
   try
   { java.lang.String classPath =
     (( java.lang.String )ClassLoader.getSystemResource
     ( className.replace( '.', java.io.File.separatorChar ) + ".class" ).getFile() ).
     substring( 1 );
     classByte = loadClassData( classPath );
     result = defineClass( className, classByte, 0, classByte.length, null );
     return result; }
   catch( final java.lang.Exception e ){ throw new java.lang.RuntimeException(e); }}
 private byte[] loadClassData
 ( final java.lang.String className )
 throws java.io.IOException
 { final java.io.File f = new java.io.File( className );
   final int size =( int )f.length();
   final byte buff[] = new byte[ size ];
   { java.io.FileInputStream fis = new java.io.FileInputStream( f );
     { java.io.DataInputStream dis = new java.io.DataInputStream( fis );
       dis.readFully( buff );
       dis.close(); }}
   return buff; }}
Francesco Devittori - 14 Jan 2006 09:51 GMT
>>Do someone with some experience with classLoaders thinks this
>>is possible? If yes, how difficult would it be?
[quoted text clipped - 6 lines]
>   Beware! The following example does not follow style rules for
>   writing good class loaders!

Very nice, thanks. This is enough for what I want to do.
However I am realizing that a custom classLoader cannot load classes
with names starting with "java.lang".
Is this true?

(another question: why do you do substring(1) in your implementation?)

Francesco
Stefan Ram - 14 Jan 2006 16:47 GMT
>Very nice, thanks. This is enough for what I want to do.
>However I am realizing that a custom classLoader cannot load
>classes with names starting with "java.lang".
>Is this true?

 I am not aware of such a restriction, but then, as I said,
 I have no clue about class loaders, except that I hacked
 together the declaration of the class "ScanLoader".
 
>(another question: why do you do substring(1) in your implementation?)

 This removes a disturbing initial character,
 I believe a slash "/".
Thomas Hawtin - 14 Jan 2006 17:44 GMT
> However I am realizing that a custom classLoader cannot load classes
> with names starting with "java.lang".

Or any qualified name starting with "java.". Presumably to avoid people
creating incompatible versions of Java. However, you can transform
classes with the instrumentation API (from 1.5).

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Francesco Devittori - 15 Jan 2006 13:34 GMT
>> However I am realizing that a custom classLoader cannot load classes
>> with names starting with "java.lang".
[quoted text clipped - 4 lines]
>
> Tom Hawtin

My problem is that I want to reload some classes to have them not
transformed by the instrumentation API...

Francesco
Roedy Green - 14 Jan 2006 05:10 GMT
On Fri, 13 Jan 2006 17:46:01 +0100, Francesco Devittori
<frenkatfrenkdtcm> wrote, quoted or indirectly quoted someone who said

>Do someone with some experience with classLoaders thinks this is
>possible? If yes, how difficult would it be?

Yes. Your problem is you must also modify the jvm byte codes because
the class name is also embedded in there.  See
http://mindprod.com/jgloss/classloader.html
and http://mindprod.com/jgloss/jasm.html
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Chris Uppal - 14 Jan 2006 13:14 GMT
> Hi all,
> I want to write a specialized classLoader that loads a class under a
> different name.

IIRC the JVM will not allow you to load a class under any name except that
which is embedded in the classfile definition.  Therefore you would have to
decode and re-encode the classfile (not impossible, not even all that
difficult, but you'll need something like the ASM library or BCEL).

   -- chris


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.