⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _chapter 9.htm

📁 Core Java 2(中文名称:JAVA 2 核心技术 卷二:高级特性)这是英文版的。
💻 HTM
📖 第 1 页 / 共 5 页
字号:
  <table cellSpacing="0" cellPadding="1" width="90%" border="0">
    <tr>
      <td vAlign="top" width="60">
      <img alt="graphics/note.gif" src="note.gif" align="left" border="0" width="54" height="53"><br>
&nbsp;</td>
      <td vAlign="top">
      <p class="docText">This technique has other uses as well, such as &quot;hot 
      deployment&quot; of servlets and Enterprise Java Beans. See
      <a class="docLink" href="http://developer.java.sun.com/developer/techtips/2000/tt1027.html" target="_blank">
      http://developer.java.sun.com/developer/TechTips/2000/tt1027.html</a> for 
      more information.</td>
    </tr>
  </table>
</div>
<h4 class="docSection2Title" id="ch09lev2sec1">Writing Your Own Class Loader</h4>
<p class="docText">To write your own class loader, you simply extend the <tt>
ClassLoader</tt> class and override the method.</p>
<pre>findClass(String className)
</pre>
<p class="docText">The <tt>loadClass</tt> method of the <tt>ClassLoader</tt> 
superclass takes care of the delegation to the parent and only calls <tt>
findClass</tt> if the class hasn't already been loaded and if the parent class 
loader was unable to load the class.</p>
<div class="docNote">
  <p class="docNoteTitle">NOTE</p>
  <table cellSpacing="0" cellPadding="1" width="90%" border="0">
    <tr>
      <td vAlign="top" width="60">
      <img alt="graphics/note.gif" src="note.gif" align="left" border="0" width="54" height="53"><br>
&nbsp;</td>
      <td vAlign="top">
      <p class="docText">In earlier versions of the SDK, programmers had to 
      override the <tt>loadClass</tt> method. That is no longer recommended.</td>
    </tr>
  </table>
</div>
<p class="docText">Your implementation of this method must:</p>
<ol class="docList">
  <span style="font-weight: bold" TYPE="1">
  <li><span style="font-weight: normal">
  <p class="docList">Load the bytecodes for the class from the local file system 
  or from some other source.</span></li>
  <li><span style="font-weight: normal">
  <p class="docList">Call the <tt>defineClass</tt> method of the <tt>ClassLoader</tt> 
  superclass to present the bytecodes to the virtual machine.</span></span></li>
</ol>
<p class="docText">In the program of <a class="docLink" href="#ch09list01">
Example 9-1</a>, we implement a class loader that loads encrypted class files. 
The program asks the user for the name of the first class to load (that is, the 
class containing <tt>main</tt>) and the decryption key. It then uses a special 
class loader to load the specified class and calls the <tt>main</tt> method. The 
class loader decrypts the specified class and all nonsystem classes that are 
referenced by it. Finally, the program calls the <tt>main</tt> method of the 
loaded class (see <a class="docLink" href="#ch09fig01">Figure 9-1</a>).</p>
<center>
<h5 id="ch09fig01" class="docFigureTitle">Figure 9-1. The <tt>ClassLoaderTest</tt> program</h5>
<p>
<img alt="graphics/09fig01.gif" src="09fig01.gif" border="0" width="403" height="341"><br>
&nbsp;</p>
</center>
<p class="docText">For simplicity, we ignore 2,000 years of progress in the 
field of cryptography and use the venerable Caesar cipher for encrypting the 
class files.</p>
<div class="docNote">
  <p class="docNoteTitle">NOTE</p>
  <table cellSpacing="0" cellPadding="1" width="90%" border="0">
    <tr>
      <td vAlign="top" width="60">
      <img alt="graphics/note.gif" src="note.gif" align="left" border="0" width="54" height="53"><br>
&nbsp;</td>
      <td vAlign="top">
      <p class="docText">David Kahn's wonderful book <i>The Codebreakers</i> 
      [Macmillan, NY, 1967, p. 84] refers to Suetonius as a historical source 
      for the Caesar cipher. Caesar shifted the 24 letters of the Roman alphabet 
      by 3 letters. At the time of this writing, the U.S. government restricts 
      the export of strong encryption methods. Therefore, we use Caesar's method 
      for our example since it is so weak that it is presumably legal for 
      export.</td>
    </tr>
  </table>
</div>
<p class="docText">Our version of the Caesar cipher has as a key a number 
between 1 and 255. To decrypt, simply add that key to every byte and reduce 
modulo 256. The <tt>Caesar.java</tt> program of
<a class="docLink" href="#ch09list02">Example 9-2</a> carries out the 
encryption.</p>
<p class="docText">In order not to confuse the regular class loader, we use a 
different extension, <tt>.caesar</tt>, for the encrypted class files.</p>
<p class="docText">To decrypt, the class loader simply subtracts the key from 
every byte. On the CD-ROM for this book, you will find four class files, 
encrypted with a key value of 3梩he traditional choice. You cannot load these 
classes via the regular bytecode interpreter, but you can run the encrypted 
program by using the custom class loader defined in our <tt>ClassLoaderTest</tt> 
program.</p>
<p class="docText">Encrypting class files has a number of practical uses 
(provided, of course, that you use a cipher stronger than the Caesar cipher). 
Without the decryption key, the class files are useless. They can neither be 
executed by a standard bytecode interpreter nor readily disassembled.</p>
<p class="docText">This means that you can use a custom class loader to 
authenticate the user of the class or to ensure that a program has been paid for 
before it will be allowed to run. Of course, encryption is only one application 
of a custom class loader. You can use other types of class loaders to solve 
other problems, for example, storing class files in a database.</p>
<h5 id="ch09list01" class="docExampleTitle">Example 9-1 ClassLoaderTest.java</h5>
<pre>  1. import java.util.*;
  2. import java.io.*;
  3. import java.lang.reflect.*;
  4. import java.awt.*;
  5. import java.awt.event.*;
  6. import javax.swing.*;
  7.
  8. /**
  9.    This program demonstrates a custom class loader that decrypts
 10.    class files.
 11. */
 12. public class ClassLoaderTest
 13. {
 14.    public static void main(String[] args)
 15.    {
 16.       JFrame frame = new ClassLoaderFrame();
 17.       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 18.       frame.show();
 19.    }
 20. }
 21.
 22. /**
 23.    This frame contains two text fields for the name of the class
 24.    to load and the decryption key.
 25. */
 26. class ClassLoaderFrame extends JFrame
 27. {
 28.    public ClassLoaderFrame()
 29.    {
 30        setTitle(&quot;ClassLoaderTest&quot;);
 31.       setSize(WIDTH, HEIGHT);
 32.       getContentPane().setLayout(new GridBagLayout());
 33.       GridBagConstraints gbc = new GridBagConstraints();
 34.       gbc.weightx = 0;
 35.       gbc.weighty = 100;
 36.       gbc.fill = GridBagConstraints.NONE;
 37.       gbc.anchor = GridBagConstraints.EAST;
 38.       add(new JLabel(&quot;Class&quot;), gbc, 0, 0, 1, 1);
 39.       add(new JLabel(&quot;Key&quot;), gbc, 0, 1, 1, 1);
 40.       gbc.weightx = 100;
 41.       gbc.fill = GridBagConstraints.HORIZONTAL;
 42.       gbc.anchor = GridBagConstraints.WEST;
 43.       add(nameField, gbc, 1, 0, 1, 1);
 44.       add(keyField, gbc, 1, 1, 1, 1);
 45.       gbc.fill = GridBagConstraints.NONE;
 46.       gbc.anchor = GridBagConstraints.CENTER;
 47.       JButton loadButton = new JButton(&quot;Load&quot;);
 48.       add(loadButton, gbc, 0, 2, 2, 1);
 49.       loadButton.addActionListener(new
 50.          ActionListener()
 51.          {
 52.             public void actionPerformed(ActionEvent event)
 53.             {
 54.               runClass(nameField.getText(), keyField.getText());
 55.             }
 56.          });
 57.    }
 58.
 59.    /**
 60.       A convenience method to add a component to given grid bag
 61.       layout locations.
 62.       @param c the component to add
 63.       @param gbc the grid bag constraints to use
 64.       @param x the x grid position
 65.       @param y the y grid position
 66.       @param w the grid width
 67.       @param h the grid height
 68.    */
 69.    public void add(Component c, GridBagConstraints gbc,
 70.       int x, int y, int w, int h)
 71.    {
 72.       gbc.gridx = x;
 73.       gbc.gridy = y;
 74.       gbc.gridwidth = w;
 75.       gbc.gridheight = h;
 76.       getContentPane().add(c, gbc);
 77.    }
 78.
 79.    /**
 80.       Runs the main method of a given class.
 81.       @param name the class name
 82.       @param key the decryption key for the class files
 83.    */
 84.    public void runClass(String name, String key)
 85.    {
 86.       try
 87.       {
 88.          ClassLoader loader
 89.             = new CryptoClassLoader(Integer.parseInt(key));
 90.          Class c = loader.loadClass(name);
 91.          String[] args = new String[] {};
 92.
 93.          Method m = c.getMethod(&quot;main&quot;,
 94.             new Class[] { args.getClass() });
 95.          m.invoke(null, new Object[] { args });
 96.       }
 97.       catch (Throwable e)
 98.       {
 99.          JOptionPane.showMessageDialog(this, e);
100.       }
101.    }
102.
103.    private JTextField keyField = new JTextField(&quot;3&quot;, 4);
104.    private JTextField nameField = new JTextField(30);
105.    private static final int WIDTH = 300;
106.    private static final int HEIGHT = 200;
107. }
108.
109. /**
110.    This class loader loads encrypted class files.
111. */
112. class CryptoClassLoader extends ClassLoader
113. {
114.    /**
115.       Constructs a crypto class loader.
116.       @param k the decryption key
117.    */
118.    public CryptoClassLoader(int k)
119.    {
120.       key = k;
121.    }
122.
123.    protected Class findClass(String name)
124.       throws ClassNotFoundException
125.    {
126.       byte[] classBytes = null;
127.       try
128.       {
129.          classBytes = loadClassBytes(name);
130.       }
131.       catch (IOException exception)
132.       {
133.          throw new ClassNotFoundException(name);
134.       }
135.
136.       Class cl = defineClass(name, classBytes,
137.          0, classBytes.length);
138.       if (cl == null)
139.             throw new ClassNotFoundException(name);
140.       return cl;
141.    }
142.
143.    /**
144.       Loads and decrypt the class file bytes.
145.       @param name the class name
146.       @return an array with the class file bytes
147.    */
148.    private byte[] loadClassBytes(String name)
149.       throws IOException
150.    {
151.       String cname = name.replace('.', '/') + &quot;.caesar&quot;;
152.       FileInputStream in = null;
153.       try
154.       {
155.          in = new FileInputStream(cname);
156.          ByteArrayOutputStream buffer
157.             = new ByteArrayOutputStream();
158.          int ch;
159.          while ((ch = in.read()) != -1)
160.          {
161.             byte b = (byte)(ch - key);
162.             buffer.write(b);
163.          }
164.          in.close();
165.          return buffer.toByteArray();
166.       }
167.       finally
168.       {
169.          if (in != null)
170.             in.close();
171.       }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -