jdk/src/share/classes/java/lang/ClassLoader.java
/**
* Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>}
* into an instance of class <tt>Class</tt>,
* with an optional <tt>ProtectionDomain</tt>. If the domain is
* <tt>null</tt>, then a default domain will be assigned to the class as
* specified in the documentation for {@link #defineClass(String, byte[],
* int, int)}. Before the class can be used it must be resolved.
*
* <p>The rules about the first class defined in a package determining the
* set of certificates for the package, and the restrictions on class names
* are identical to those specified in the documentation for {@link
* #defineClass(String, byte[], int, int, ProtectionDomain)}.
*
* <p> An invocation of this method of the form
* <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>
* <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
* result as the statements
*
* <blockquote><tt>
* ...<br>
* byte[] temp = new byte[</tt><i>bBuffer</i><tt>.{@link
* java.nio.ByteBuffer#remaining remaining}()];<br>
* </tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#get(byte[])
* get}(temp);<br>
* return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
* </tt><i>cl</i><tt>.defineClass}(</tt><i>name</i><tt>, temp, 0,
* temp.length, </tt><i>pd</i><tt>);<br>
* </tt></blockquote>
*
* @param name
* The expected <a href="#name">binary name</a>. of the class, or
* <tt>null</tt> if not known
*
* @param b
* The bytes that make up the class data. The bytes from positions
* <tt>b.position()</tt> through <tt>b.position() + b.limit() -1
* </tt> should have the format of a valid class file as defined by
* <cite>The Java™ Virtual Machine Specification</cite>.
*
* @param protectionDomain
* The ProtectionDomain of the class, or <tt>null</tt>.
*
* @return The <tt>Class</tt> object created from the data,
* and optional <tt>ProtectionDomain</tt>.
*
* @throws ClassFormatError
* If the data did not contain a valid class.
*
* @throws NoClassDefFoundError
* If <tt>name</tt> is not equal to the <a href="#name">binary
* name</a> of the class specified by <tt>b</tt>
*
* @throws SecurityException
* If an attempt is made to add this class to a package that
* contains classes that were signed by a different set of
* certificates than this class, or if <tt>name</tt> begins with
* "<tt>java.</tt>".
*
* @see #defineClass(String, byte[], int, int, ProtectionDomain)
*
* @since 1.5
*/
protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
ProtectionDomain protectionDomain)
throws ClassFormatError
{
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
int len = b.remaining();
{- -------------------------------------------
(1) b 引数が direct ByteBufer でない場合,
引数違いの java.lang.ClassLoader.defineClass() を呼んでクラスのロード処理を行い,
結果をリターンする.
---------------------------------------- -}
// Use byte[] if not a direct ByteBufer:
if (!b.isDirect()) {
if (b.hasArray()) {
return defineClass(name, b.array(),
b.position() + b.arrayOffset(), len,
protectionDomain);
} else {
// no array, or read-only array
byte[] tb = new byte[len];
b.get(tb); // get bytes out of byte buffer.
return defineClass(name, tb, 0, len, protectionDomain);
}
}
{- -------------------------------------------
(1) preDefineClass() を呼んで, 使用する protection domain を調整する.
また, name 引数で指定されたクラスが, ロード対象として不正ではないかどうかのチェックも行う.
(不正な場合は, 例外が送出される)
---------------------------------------- -}
protectionDomain = preDefineClass(name, protectionDomain);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
Class c = null;
String source = defineClassSourceLocation(protectionDomain);
{- -------------------------------------------
(1) defineClass2() を呼んで, クラスのロード処理を行う.
なお, もし ClassFormatError になった場合は,
defineTransformedClass() でのロード処理を試みる.
(このメソッドでは, 登録されている ClassFileTransformer でバイトコードを変更してからロードを行う)
---------------------------------------- -}
try {
c = defineClass2(name, b, b.position(), len, protectionDomain,
source);
} catch (ClassFormatError cfe) {
byte[] tb = new byte[len];
b.get(tb); // get bytes out of byte buffer.
c = defineTransformedClass(name, tb, 0, len, protectionDomain, cfe,
source);
}
{- -------------------------------------------
(1)
---------------------------------------- -}
postDefineClass(c, protectionDomain);
{- -------------------------------------------
(1) 結果をリターン
---------------------------------------- -}
return c;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.