Implementation of a simple custom classloader

Source: Internet
Author: User



Implementation of a simple custom classloader
Kert original (Participation score: 759, expert score: 960) published: Update: Version: 1.0 read:9737Times



In many cases, some custom classloader is used instead of the system class loader. Most of the time, people do this because they cannot predict which classes are needed during the runtime during compilation. Especially in those appservers, such as Tomcat, aveon-phonix, and JBoss. OrProgramSome plug-in functions are provided. You can add your own functions after the program is compiled, such as Ant and JXTA-shell. It is easy to customize a classloader. Generally, you only need to understand a few methods.

A simple custom classloader inherits from the classloader class. Here we need to create a classloader that can specify a path at runtime to load the class under this path.

Generally, we use the classloader. loadclass (string): class method. By providing a class name, we will get a corresponding class instance. Therefore, as long as we make a small change to this method, we can achieve our aspirations.

Source code:

  1. Protected Synchronized ClassLoadclass (StringName,BooleanRESOLVE)Throws Classnotfoundexception{
  2. // First, check if the class has already been loaded
  3. ClassC = findloadedclass (name );
  4. If(C =Null){
  5. Try{
  6. If(Parent! =Null){
  7. C = parent. loadclass (name,False);
  8. }Else{
  9. C = findbootstrapclass0 (name );
  10. }
  11. }Catch(ClassnotfoundexceptionE ){
  12. // If still not found, then call findclass in order
  13. // To find the class.
  14. C = findclass (name );
  15. }
  16. }
  17. If(RESOLVE ){
  18. Resolveclass (C );
  19. }
  20. ReturnC;
  21. }

Source from classloader. Java

First, check javaapi DOC: the steps of the default loadclass method are shown above.

1. call findloadedclass (string): The class checks whether the class has been loaded. The JVM specification specifies that classloader can cache the class it loads, therefore, if a class has been loaded, you can directly obtain it from the cache.

2. Call its parent loadclass () method. If the parent is empty, use the Class Loader (the famous Bootstrap classloader) in the JVM ).

3. If neither of the above two steps is found, call the findclass (string) method to find and load the class.

There is another saying that after Java 1.2, we encourage users to inherit the findclass (string) method to implement their own class loader instead of inheriting the loadclass (string) method.

In this case, we will do this first :)

  1. Public ClassAnotherclassloaderExtends Classloader{
  2. Private StringBasedir;Private Static FinalLogger log =
  3. Logger. getlogger (anotherclassloader.Class);
  4. PublicAnotherclassloader (ClassloaderParent,StringBasedir ){
  5. Super(Parent );
  6. This. Basedir = basedir;
  7. }
  8. Protected ClassFindclass (StringName)
  9. Throws Classnotfoundexception{
  10. Log. debug ("findclass" + name );
  11. Byte[] Bytes = loadclassbytes (name );
  12. ClassTheclass = defineclass (name, bytes, 0, bytes.Length);//
  13. If(Theclass =Null)
  14. Throw New Classformaterror();
  15. ReturnTheclass;
  16. }
  17. Private Byte[] Loadclassbytes (StringClassname)Throws
  18. Classnotfoundexception{
  19. Try{
  20. StringClassfile = getclassfile (classname );
  21. Fileinputstream FCM =NewFileinputstream (classfile );
  22. Filechannel filec = FS. getchannel ();
  23. Bytearrayoutputstream baos =NewBytearrayoutputstream ();
  24. Writablebytechannel outc = channels. newchannel (baos );
  25. Bytebuffer buffer = bytebuffer. allocatedirect (1024 );
  26. While(True){
  27. IntI = filec. Read (buffer );
  28. If(I = 0 | I =-1 ){
  29. Break;
  30. }
  31. Buffer. Flip ();
  32. Outc. Write (buffer );
  33. Buffer. Clear ();
  34. }
  35. FCM. Close ();
  36. ReturnBaos. tobytearray ();
  37. }Catch(Ioexception fnfe ){
  38. Throw New Classnotfoundexception(Classname );
  39. }
  40. }
  41. Private StringGetclassfile (StringName ){
  42. StringbufferSB =New Stringbuffer(Basedir );
  43. Name = Name. Replace ('.', file. separatorchar) + ". Class ";
  44. SB. append (file. Separator + name );
  45. ReturnSB. tostring ();
  46. }
  47. }

[I] PS: here we use NiO of jdk1.4Code:) [/I]

Very simple code. The key is in A. We use the defineclass method to convert the binary array obtained from the class file to the corresponding class instance. Defineclass is a native method. It identifies the class file format for us, analyzes and reads the corresponding data structure, and generates a class instance.

Before we finish, we just found the class released in a directory, and there are resources. Sometimes we use class. getresource (): URL to obtain the corresponding resource file. If the above classloader is used only, the corresponding return value is null.

Let's take a look at the internal structure of the original classloader.

    1. PublicJava.net.URLGetresource (StringName ){
    2. Name = resolvename (name );
    3. ClassloaderCL = getclassloader0 ();// Here
    4. If(CL =Null){
    5. // A system class.
    6. Return Classloader. Getsystemresource (name );
    7. }
    8. ReturnCl. getresource (name );}

It turns out that the classloader that loads this class gets the resource.

    1. PublicURL getresource (StringName ){
    2. URL;
    3. If(Parent! =Null){
    4. Url = parent. getresource (name );
    5. }Else{
    6. Url = getbootstrapresource (name );
    7. }
    8. If(Url =Null){
    9. Url = findresource (name );// Here
    10. }
    11. ReturnURL;
    12. }

In this case, you only need to inherit the findresource (string) method. Modify the following code:

  1. // A new findresource Method
  2. ProtectedURL findresource (StringName ){
  3. Log. debug ("findresource" + name );
  4. Try{
  5. URL url =Super. Findresource (name );
  6. If(URL! =Null)
  7. ReturnURL;
  8. Url =NewURL ("file: //" + convername (name ));
  9. // Simplified processing. All resources are obtained from the file system.
  10. ReturnURL;
  11. }Catch(Malformedurlexception mue ){
  12. Log. Error ("findresource", mue );
  13. Return Null;
  14. }
  15. }
  16. Private StringConvername (StringName ){
  17. StringbufferSB =New Stringbuffer(Basedir );
  18. Name = Name. Replace ('.', file. separatorchar );
  19. SB. append (file. Separator + name );
  20. ReturnSB. tostring ();
  21. }

Now, a simple custom classloader is ready. You can add other spices (such as security check and class file modification) to suit your taste :)

----------------

I am not guru, but nonsenser

& Lt; TD align = "right" width = "70%" & gt;
copyright notice: Write to the author
This article does the article help you? Vote: Yes NO voting result: 9 0
other articles by the author:

  • P2P introduction
  • Tomcat reload, story to be told
  • JMX notes ---- Part I (hellojmx)
  • Top Ten Reasons for Java III!
  • JAVA idioms-parameter classes (from C2)

all articles by the author

comments: efly score: 1044 expert score: 1820 published on:
resolveclass is recommended. This method loads the class into classloader for future calls or other class calls.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.