Skip to content
Commits on Source (8)
...@@ -12,4 +12,4 @@ tmp/ ...@@ -12,4 +12,4 @@ tmp/
.project .project
.settings .settings
TestLog.xml TestLog.xml
*~
Java bytecode engineering toolkit Java bytecode engineering toolkit
### [Javassist version 3](http://www.javassist.org) ### [Javassist version 3](http://www.javassist.org)
Copyright (C) 1999-2018 by Shigeru Chiba, All rights reserved. Copyright (C) 1999-2019 by Shigeru Chiba, All rights reserved.
Javassist (JAVA programming ASSISTant) makes Java bytecode manipulation Javassist (JAVA programming ASSISTant) makes Java bytecode manipulation
simple. It is a class library for editing bytecodes in Java; it enables Java simple. It is a class library for editing bytecodes in Java; it enables Java
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<h1>Javassist version 3</h1> <h1>Javassist version 3</h1>
<h3>Copyright (C) 1999-2018 by Shigeru Chiba, All rights reserved.</h3> <h3>Copyright (C) 1999-2019 by Shigeru Chiba, All rights reserved.</h3>
<p><br></p> <p><br></p>
...@@ -281,9 +281,29 @@ see javassist.Dump. ...@@ -281,9 +281,29 @@ see javassist.Dump.
<h2>Changes</h2> <h2>Changes</h2>
<p>-version 3.25 on April 16, 2019
<ul>
<li>GitHub Issue #72 (PR #231), #241, #242 (PR #243), PR #244,
#246 (PR #247), PR #250, #252 (PR #253), PR #254.
</ul>
<p>-version 3.24.1 on December 9, 2018
<ul>
<li>GitHub Issue #228, #229</li>
<ul>
</p>
<p>-version 3.24 on November 1, 2018
<ul>
<li>Java 11 supports.</li>
<li>JIRA JASSIST-267.</li>
<li>Github PR #218.</li>
</ul>
</p>
<p>-version 3.23.1 on July 2, 2018 <p>-version 3.23.1 on July 2, 2018
<ul> <ul>
<li>Github pull issue #171.</li> <li>Github PR #171.</li>
</ul> </ul>
</p> </p>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<project name="javassist" default="jar" basedir="."> <project name="javassist" default="jar" basedir=".">
<property name="dist-version" value="javassist-3.23.1-GA"/> <property name="dist-version" value="javassist-3.25.0-GA"/>
<property environment="env"/> <property environment="env"/>
<property name="target.jar" value="javassist.jar"/> <property name="target.jar" value="javassist.jar"/>
...@@ -74,13 +74,13 @@ ...@@ -74,13 +74,13 @@
</javac> </javac>
</target> </target>
<target name="compile16" depends="prepare"> <target name="compile18" depends="prepare">
<javac srcdir="${src.dir}" <javac srcdir="${src.dir}"
destdir="${build.classes.dir}" destdir="${build.classes.dir}"
debug="on" debug="on"
deprecation="on" deprecation="on"
source="1.6" source="1.7"
target="1.6" target="1.7"
optimize="off" optimize="off"
includeantruntime="true" includeantruntime="true"
includes="**"> includes="**">
...@@ -181,7 +181,7 @@ ...@@ -181,7 +181,7 @@
to ${build.classes.dir}.</echo> to ${build.classes.dir}.</echo>
</target> </target>
<target name="jar" depends="compile16"> <target name="jar" depends="compile18">
<jar jarfile="${target.jar}" update="true" manifest="${src.dir}/META-INF/MANIFEST.MF"> <jar jarfile="${target.jar}" update="true" manifest="${src.dir}/META-INF/MANIFEST.MF">
<fileset dir="${build.classes.dir}"> <fileset dir="${build.classes.dir}">
<include name="**/*.class"/> <include name="**/*.class"/>
......
javassist (1:3.25.0-1) unstable; urgency=medium
* Team upload.
* New upstream release
- Refreshed the patches
* Standards-Version updated to 4.4.0
-- Emmanuel Bourg <ebourg@apache.org> Mon, 15 Jul 2019 11:09:39 +0200
javassist (1:3.23.1-1) unstable; urgency=medium javassist (1:3.23.1-1) unstable; urgency=medium
* Team upload. * Team upload.
......
...@@ -12,7 +12,7 @@ Build-Depends: ...@@ -12,7 +12,7 @@ Build-Depends:
libmaven-bundle-plugin-java, libmaven-bundle-plugin-java,
libmaven-javadoc-plugin-java, libmaven-javadoc-plugin-java,
maven-debian-helper (>= 2.1) maven-debian-helper (>= 2.1)
Standards-Version: 4.2.1 Standards-Version: 4.4.0
Vcs-Git: https://salsa.debian.org/java-team/javassist.git Vcs-Git: https://salsa.debian.org/java-team/javassist.git
Vcs-Browser: https://salsa.debian.org/java-team/javassist Vcs-Browser: https://salsa.debian.org/java-team/javassist
Homepage: http://jboss-javassist.github.io/javassist/ Homepage: http://jboss-javassist.github.io/javassist/
......
...@@ -19,10 +19,10 @@ Forwarded: not-needed ...@@ -19,10 +19,10 @@ Forwarded: not-needed
ClassPool pool = new ClassPool(true); ClassPool pool = new ClassPool(true);
for(int paths=0; paths<50; paths++) { for(int paths=0; paths<50; paths++) {
pool.appendClassPath(JAVASSIST_JAR); pool.appendClassPath(JAVASSIST_JAR);
@@ -693,7 +693,7 @@ @@ -694,7 +694,7 @@
assertTrue("performance test (the next try may succeed): " + t2 + " < 6 * " + t1,
t2 < t1 * 6); t2 < t1 * 6);
assertTrue(t3 + " < 3 * " + t1, t3 < t1 * 3); assertTrue("performance test (the next try may succeed): " + t3 + " < 3 * " + t1,
t3 < t1 * 3);
- } - }
+ }*/ + }*/
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
Javassist (JAVA programming ASSISTant) makes Java bytecode manipulation Javassist (JAVA programming ASSISTant) makes Java bytecode manipulation
simple. It is a class library for editing bytecodes in Java. simple. It is a class library for editing bytecodes in Java.
</description> </description>
<version>3.23.1-GA</version> <version>3.25.0-GA</version>
<name>Javassist</name> <name>Javassist</name>
<url>http://www.javassist.org/</url> <url>http://www.javassist.org/</url>
...@@ -151,10 +151,10 @@ ...@@ -151,10 +151,10 @@
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version> <version>3.2</version>
<configuration> <configuration>
<source>1.6</source> <source>1.7</source>
<target>1.6</target> <target>1.7</target>
<testSource>1.9</testSource> <testSource>11</testSource>
<testTarget>1.9</testTarget> <testTarget>11</testTarget>
<testCompilerArgument>-parameters</testCompilerArgument> <testCompilerArgument>-parameters</testCompilerArgument>
</configuration> </configuration>
</plugin> </plugin>
...@@ -202,9 +202,15 @@ ...@@ -202,9 +202,15 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0-M1</version> <version>3.0.1</version>
<configuration> <configuration>
<attach>true</attach> <attach>true</attach>
<excludePackageNames>javassist.compiler:javassist.convert:javassist.scopedpool:javassist.bytecode.stackmap</excludePackageNames>
<bottom><![CDATA[<i>Javassist, a Java-bytecode translator toolkit.<br>
Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.</i>]]></bottom>
<show>public</show>
<nohelp>true</nohelp>
<doclint>none</doclint>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
......
Specification-Title: Javassist Specification-Title: Javassist
Specification-Vendor: Shigeru Chiba, www.javassist.org Specification-Vendor: Shigeru Chiba, www.javassist.org
Specification-Version: 3.23.1-GA Specification-Version: 3.25.0-GA
Main-Class: javassist.CtClass Main-Class: javassist.CtClass
Automatic-Module-Name: org.javassist
...@@ -17,9 +17,12 @@ ...@@ -17,9 +17,12 @@
package javassist; package javassist;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
/** /**
* A <code>ByteArrayClassPath</code> contains bytes that is served as * A <code>ByteArrayClassPath</code> contains bytes that is served as
...@@ -86,12 +89,34 @@ public class ByteArrayClassPath implements ClassPath { ...@@ -86,12 +89,34 @@ public class ByteArrayClassPath implements ClassPath {
if(this.classname.equals(classname)) { if(this.classname.equals(classname)) {
String cname = classname.replace('.', '/') + ".class"; String cname = classname.replace('.', '/') + ".class";
try { try {
// return new File(cname).toURL(); return new URL(null, "file:/ByteArrayClassPath/" + cname, new BytecodeURLStreamHandler());
return new URL("file:/ByteArrayClassPath/" + cname);
} }
catch (MalformedURLException e) {} catch (MalformedURLException e) {}
} }
return null; return null;
} }
private class BytecodeURLStreamHandler extends URLStreamHandler {
protected URLConnection openConnection(final URL u) {
return new BytecodeURLConnection(u);
}
}
private class BytecodeURLConnection extends URLConnection {
protected BytecodeURLConnection(URL url) {
super(url);
}
public void connect() throws IOException {
}
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(classfile);
}
public int getContentLength() {
return classfile.length;
}
}
} }
...@@ -1023,16 +1023,23 @@ public class ClassPool { ...@@ -1023,16 +1023,23 @@ public class ClassPool {
* the <code>getClassLoader()</code> method. * the <code>getClassLoader()</code> method.
* If the program is running on some application * If the program is running on some application
* server, the context class loader might be inappropriate to load the * server, the context class loader might be inappropriate to load the
* class. * class.</p>
* *
* <p>This method is provided for convenience. If you need more * <p>This method is provided for convenience. If you need more
* complex functionality, you should write your own class loader. * complex functionality, you should write your own class loader.
* *
* <p><b>Warining:</b> A Class object returned by this method may not * <p><b>Warining:</b>
* This method should not be used in Java 11 or later.
* Use {@link #toClass(CtClass,Class)}.
* </p>
*
* <p><b>Warining:</b>
* A Class object returned by this method may not
* work with a security manager or a signed jar file because a * work with a security manager or a signed jar file because a
* protection domain is not specified. * protection domain is not specified.</p>
* *
* @see #toClass(CtClass, java.lang.ClassLoader, ProtectionDomain) * @see #toClass(CtClass,Class)
* @see #toClass(CtClass,Class,java.lang.ClassLoader,ProtectionDomain)
* @see #getClassLoader() * @see #getClassLoader()
*/ */
public Class toClass(CtClass clazz) throws CannotCompileException { public Class toClass(CtClass clazz) throws CannotCompileException {
...@@ -1066,21 +1073,21 @@ public class ClassPool { ...@@ -1066,21 +1073,21 @@ public class ClassPool {
/** /**
* Converts the class to a <code>java.lang.Class</code> object. * Converts the class to a <code>java.lang.Class</code> object.
* Do not override this method any more at a subclass because * Do not override this method any more at a subclass because
* <code>toClass(CtClass)</code> never calls this method. * {@link #toClass(CtClass)} will never calls this method.
* *
* <p><b>Warining:</b> A Class object returned by this method may not * <p><b>Warining:</b> A Class object returned by this method may not
* work with a security manager or a signed jar file because a * work with a security manager or a signed jar file because a
* protection domain is not specified. * protection domain is not specified.
* *
* @deprecated Replaced by {@link #toClass(CtClass,ClassLoader,ProtectionDomain)}. * @deprecated Replaced by {@link #toClass(CtClass,Class,ClassLoader,ProtectionDomain)}.
* A subclass of <code>ClassPool</code> that has been * A subclass of <code>ClassPool</code> that has been
* overriding this method should be modified. It should override * overriding this method should be modified. It should override
* {@link #toClass(CtClass,ClassLoader,ProtectionDomain)}. * {@link #toClass(CtClass,Class,ClassLoader,ProtectionDomain)}.
*/ */
public Class toClass(CtClass ct, ClassLoader loader) public Class toClass(CtClass ct, ClassLoader loader)
throws CannotCompileException throws CannotCompileException
{ {
return toClass(ct, loader, null); return toClass(ct, null, loader, null);
} }
/** /**
...@@ -1092,7 +1099,7 @@ public class ClassPool { ...@@ -1092,7 +1099,7 @@ public class ClassPool {
* loaded by the given class loader to construct a * loaded by the given class loader to construct a
* <code>java.lang.Class</code> object. Since a private method * <code>java.lang.Class</code> object. Since a private method
* on the class loader is invoked through the reflection API, * on the class loader is invoked through the reflection API,
* the caller must have permissions to do that. * the caller must have permissions to do that.</p>
* *
* <p>An easy way to obtain <code>ProtectionDomain</code> object is * <p>An easy way to obtain <code>ProtectionDomain</code> object is
* to call <code>getProtectionDomain()</code> * to call <code>getProtectionDomain()</code>
...@@ -1100,8 +1107,9 @@ public class ClassPool { ...@@ -1100,8 +1107,9 @@ public class ClassPool {
* class belongs to. * class belongs to.
* *
* <p>This method is provided for convenience. If you need more * <p>This method is provided for convenience. If you need more
* complex functionality, you should write your own class loader. * complex functionality, you should write your own class loader.</p>
* *
* @param ct the class converted into {@code java.lang.Class}.
* @param loader the class loader used to load this class. * @param loader the class loader used to load this class.
* For example, the loader returned by * For example, the loader returned by
* <code>getClassLoader()</code> can be used * <code>getClassLoader()</code> can be used
...@@ -1112,13 +1120,117 @@ public class ClassPool { ...@@ -1112,13 +1120,117 @@ public class ClassPool {
* *
* @see #getClassLoader() * @see #getClassLoader()
* @since 3.3 * @since 3.3
* @deprecated Replaced by {@link #toClass(CtClass,Class,ClassLoader,ProtectionDomain)}.
*/ */
public Class toClass(CtClass ct, ClassLoader loader, ProtectionDomain domain) public Class toClass(CtClass ct, ClassLoader loader, ProtectionDomain domain)
throws CannotCompileException throws CannotCompileException
{
return toClass(ct, null, loader, domain);
}
/**
* Converts the class to a <code>java.lang.Class</code> object.
* Once this method is called, further modifications are not allowed
* any more.
*
* <p>This method is available in Java 9 or later.
* It loads the class
* by using {@code java.lang.invoke.MethodHandles} with {@code neighbor}.
* </p>
*
* @param ct the class converted into {@code java.lang.Class}.
* @param neighbor a class belonging to the same package that
* the converted class belongs to.
* @since 3.24
*/
public Class<?> toClass(CtClass ct, Class<?> neighbor)
throws CannotCompileException
{
try {
return javassist.util.proxy.DefineClassHelper.toClass(neighbor,
ct.toBytecode());
}
catch (IOException e) {
throw new CannotCompileException(e);
}
}
/**
* Converts the class to a <code>java.lang.Class</code> object.
* Once this method is called, further modifications are not allowed
* any more.
*
* <p>This method is available in Java 9 or later.
* It loads the class
* by using the given {@code java.lang.invoke.MethodHandles.Lookup}.
* </p>
*
* @param ct the class converted into {@code java.lang.Class}.
* @since 3.24
*/
public Class<?> toClass(CtClass ct,
java.lang.invoke.MethodHandles.Lookup lookup)
throws CannotCompileException
{
try {
return javassist.util.proxy.DefineClassHelper.toClass(lookup,
ct.toBytecode());
}
catch (IOException e) {
throw new CannotCompileException(e);
}
}
/**
* Converts the class to a <code>java.lang.Class</code> object.
* Once this method is called, further modifications are not allowed
* any more.
*
* <p>When the JVM is Java 11 or later, this method loads the class
* by using {@code java.lang.invoke.MethodHandles} with {@code neighbor}.
* The other arguments {@code loader} and {@code domain} are not used;
* so they can be null.
* </p>
*
* <p>Otherwise, or when {@code neighbor} is null,
* the class file represented by the given <code>CtClass</code> is
* loaded by the given class loader to construct a
* <code>java.lang.Class</code> object. Since a private method
* on the class loader is invoked through the reflection API,
* the caller must have permissions to do that.
*
* <p>An easy way to obtain <code>ProtectionDomain</code> object is
* to call <code>getProtectionDomain()</code>
* in <code>java.lang.Class</code>. It returns the domain that the
* class belongs to.
*
* <p>If your program is for only Java 9 or later, don't use this method.
* Use {@link #toClass(CtClass,Class)} or
* {@link #toClass(CtClass,java.lang.invoke.MethodHandles.Lookup)}.
* </p>
*
* @param ct the class converted into {@code java.lang.Class}.
* @param neighbor a class belonging to the same package that
* the converted class belongs to.
* It can be null.
* @param loader the class loader used to load this class.
* For example, the loader returned by
* <code>getClassLoader()</code> can be used
* for this parameter.
* @param domain the protection domain for the class.
* If it is null, the default domain created
* by <code>java.lang.ClassLoader</code> is used.
*
* @see #getClassLoader()
* @since 3.24
*/
public Class toClass(CtClass ct, Class<?> neighbor, ClassLoader loader,
ProtectionDomain domain)
throws CannotCompileException
{ {
try { try {
return javassist.util.proxy.DefineClassHelper.toClass(ct.getName(), return javassist.util.proxy.DefineClassHelper.toClass(ct.getName(),
loader, domain, ct.toBytecode()); neighbor, loader, domain, ct.toBytecode());
} }
catch (IOException e) { catch (IOException e) {
throw new CannotCompileException(e); throw new CannotCompileException(e);
...@@ -1134,11 +1246,7 @@ public class ClassPool { ...@@ -1134,11 +1246,7 @@ public class ClassPool {
* <code>getPackage()</code> on the <code>Class</code> object returned * <code>getPackage()</code> on the <code>Class</code> object returned
* by <code>toClass()</code> will return a non-null object.</p> * by <code>toClass()</code> will return a non-null object.</p>
* *
* <p>The jigsaw module introduced by Java 9 has broken this method. * <p>The jigsaw module introduced by Java 9 has broken this method.</p>
* In Java 9 or later, the VM argument
* <code>--add-opens java.base/java.lang=ALL-UNNAMED</code>
* has to be given to the JVM so that this method can run.
* </p>
* *
* @param loader the class loader passed to <code>toClass()</code> or * @param loader the class loader passed to <code>toClass()</code> or
* the default one obtained by <code>getClassLoader()</code>. * the default one obtained by <code>getClassLoader()</code>.
......
...@@ -159,7 +159,9 @@ final class JarClassPath implements ClassPath { ...@@ -159,7 +159,9 @@ final class JarClassPath implements ClassPath {
URL jarURL = find(classname); URL jarURL = find(classname);
if (null != jarURL) if (null != jarURL)
try { try {
return jarURL.openConnection().getInputStream(); java.net.URLConnection con = jarURL.openConnection();
con.setUseCaches(false);
return con.getInputStream();
} }
catch (IOException e) { catch (IOException e) {
throw new NotFoundException("broken jar file?: " throw new NotFoundException("broken jar file?: "
......
...@@ -25,6 +25,7 @@ import javassist.convert.TransformAccessArrayField; ...@@ -25,6 +25,7 @@ import javassist.convert.TransformAccessArrayField;
import javassist.convert.TransformAfter; import javassist.convert.TransformAfter;
import javassist.convert.TransformBefore; import javassist.convert.TransformBefore;
import javassist.convert.TransformCall; import javassist.convert.TransformCall;
import javassist.convert.TransformCallToStatic;
import javassist.convert.TransformFieldAccess; import javassist.convert.TransformFieldAccess;
import javassist.convert.TransformNew; import javassist.convert.TransformNew;
import javassist.convert.TransformNewClass; import javassist.convert.TransformNewClass;
...@@ -406,6 +407,42 @@ public class CodeConverter { ...@@ -406,6 +407,42 @@ public class CodeConverter {
= new TransformCall(transformers, oldMethodName, newMethod); = new TransformCall(transformers, oldMethodName, newMethod);
} }
/**
* Redirect non-static method invocations in a method body to a static
* method. The return type must be same with the originally invoked method.
* As parameters, the static method receives
* the target object and all the parameters to the originally invoked
* method. For example, if the originally invoked method is
* <code>move()</code>:
*
* <pre>class Point {
* Point move(int x, int y) { ... }
* }</pre>
*
* <p>Then the static method must be something like this:
*
* <pre>class Verbose {
* static Point print(Point target, int x, int y) { ... }
* }</pre>
*
* <p>The <code>CodeConverter</code> would translate bytecode
* equivalent to:
*
* <pre>Point p2 = p.move(x + y, 0);</pre>
*
* <p>into the bytecode equivalent to:
*
* <pre>Point p2 = Verbose.print(p, x + y, 0);</pre>
*
* @param origMethod original method
* @param staticMethod static method
*/
public void redirectMethodCallToStatic(CtMethod origMethod,
CtMethod staticMethod) {
transformers = new TransformCallToStatic(transformers, origMethod,
staticMethod);
}
/** /**
* Insert a call to another method before an existing method call. * Insert a call to another method before an existing method call.
* That "before" method must be static. The return type must be * That "before" method must be static. The return type must be
......
...@@ -782,7 +782,7 @@ public abstract class CtBehavior extends CtMember { ...@@ -782,7 +782,7 @@ public abstract class CtBehavior extends CtMember {
Modifier.isStatic(getModifiers())); Modifier.isStatic(getModifiers()));
jv.recordParamNames(ca, nvars); jv.recordParamNames(ca, nvars);
jv.recordLocalVariables(ca, 0); jv.recordLocalVariables(ca, 0);
jv.recordType(getReturnType0()); jv.recordReturnType(getReturnType0(), false);
jv.compileStmnt(src); jv.compileStmnt(src);
Bytecode b = jv.getBytecode(); Bytecode b = jv.getBytecode();
int stack = b.getMaxStack(); int stack = b.getMaxStack();
......
...@@ -69,7 +69,7 @@ public abstract class CtClass { ...@@ -69,7 +69,7 @@ public abstract class CtClass {
/** /**
* The version number of this release. * The version number of this release.
*/ */
public static final String version = "3.23.1-GA"; public static final String version = "3.25.0-GA";
/** /**
* Prints the version number and the copyright notice. * Prints the version number and the copyright notice.
...@@ -80,7 +80,7 @@ public abstract class CtClass { ...@@ -80,7 +80,7 @@ public abstract class CtClass {
*/ */
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Javassist version " + CtClass.version); System.out.println("Javassist version " + CtClass.version);
System.out.println("Copyright (C) 1999-2018 Shigeru Chiba." System.out.println("Copyright (C) 1999-2019 Shigeru Chiba."
+ " All Rights Reserved."); + " All Rights Reserved.");
} }
...@@ -1261,21 +1261,86 @@ public abstract class CtClass { ...@@ -1261,21 +1261,86 @@ public abstract class CtClass {
* server, the context class loader might be inappropriate to load the * server, the context class loader might be inappropriate to load the
* class. * class.
* *
* <p><b>Warning:</b> In Java 11 or later, the call to this method will
* print a warning message:</p>
* <blockquote><pre>
* WARNING: An illegal reflective access operation has occurred
* WARNING: Illegal reflective access by javassist.util.proxy.SecurityActions$3 ...
* WARNING: Please consider reporting this to the maintainers of javassist.util.proxy.SecurityActions$3
* WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
* WARNING: All illegal access operations will be denied in a future release
* </pre></blockquote>
* <p>To avoid this message, use {@link #toClass(Class)}
* or {@link #toClass(java.lang.invoke.MethodHandles.Lookup)}.
* {@link #toClass()} will be unavailable in a future release.
* </p>
*
* <p><b>Warning:</b> A Class object returned by this method may not
* work with a security manager or a signed jar file because a
* protection domain is not specified.</p>
*
* <p>Note: this method calls <code>toClass()</code>
* in <code>ClassPool</code>.</p>
*
* @see #toClass(java.lang.invoke.MethodHandles.Lookup)
* @see #toClass(Class)
* @see ClassPool#toClass(CtClass)
*/
public Class<?> toClass() throws CannotCompileException {
return getClassPool().toClass(this);
}
/**
* Converts this class to a <code>java.lang.Class</code> object.
* Once this method is called, further modifications are not
* allowed any more.
*
* <p>This method is provided for convenience. You should use
* {@code toClass(Lookup)} for better compatibility with the
* module system.
*
* <p>Note: this method calls <code>toClass()</code>
* in <code>ClassPool</code>.
*
* <p><b>Warning:</b> A Class object returned by this method may not
* work with a security manager or a signed jar file because a
* protection domain is not specified.
*
* @param neighbor A class belonging to the same package that this
* class belongs to. It is used to load the class.
* @see ClassPool#toClass(CtClass,Class)
* @see #toClass(java.lang.invoke.MethodHandles.Lookup)
* @since 3.24
*/
public Class<?> toClass(Class<?> neighbor) throws CannotCompileException
{
return getClassPool().toClass(this, neighbor);
}
/**
* Converts this class to a <code>java.lang.Class</code> object.
* Once this method is called, further modifications are not
* allowed any more.
*
* <p>This method is provided for convenience. If you need more * <p>This method is provided for convenience. If you need more
* complex functionality, you should write your own class loader. * complex functionality, you should write your own class loader.
* *
* <p>Note: this method calls <code>toClass()</code> * <p>Note: this method calls <code>toClass()</code>
* in <code>ClassPool</code>. * in <code>ClassPool</code>.
* *
* <p><b>Warining:</b> A Class object returned by this method may not * <p><b>Warning:</b> A Class object returned by this method may not
* work with a security manager or a signed jar file because a * work with a security manager or a signed jar file because a
* protection domain is not specified. * protection domain is not specified.
* *
* @see #toClass(java.lang.ClassLoader,ProtectionDomain) * @param lookup used when loading the class. It has to have
* @see ClassPool#toClass(CtClass) * an access right to define a new class.
* @see ClassPool#toClass(CtClass,java.lang.invoke.MethodHandles.Lookup)
* @since 3.24
*/ */
public Class<?> toClass() throws CannotCompileException { public Class<?> toClass(java.lang.invoke.MethodHandles.Lookup lookup)
return getClassPool().toClass(this); throws CannotCompileException
{
return getClassPool().toClass(this, lookup);
} }
/** /**
...@@ -1316,13 +1381,13 @@ public abstract class CtClass { ...@@ -1316,13 +1381,13 @@ public abstract class CtClass {
if (loader == null) if (loader == null)
loader = cp.getClassLoader(); loader = cp.getClassLoader();
return cp.toClass(this, loader, domain); return cp.toClass(this, null, loader, domain);
} }
/** /**
* Converts this class to a <code>java.lang.Class</code> object. * Converts this class to a <code>java.lang.Class</code> object.
* *
* <p><b>Warining:</b> A Class object returned by this method may not * <p><b>Warning:</b> A Class object returned by this method may not
* work with a security manager or a signed jar file because a * work with a security manager or a signed jar file because a
* protection domain is not specified. * protection domain is not specified.
* *
...@@ -1332,7 +1397,7 @@ public abstract class CtClass { ...@@ -1332,7 +1397,7 @@ public abstract class CtClass {
public final Class<?> toClass(ClassLoader loader) public final Class<?> toClass(ClassLoader loader)
throws CannotCompileException throws CannotCompileException
{ {
return getClassPool().toClass(this, loader); return getClassPool().toClass(this, null, loader, null);
} }
/** /**
...@@ -1405,7 +1470,7 @@ public abstract class CtClass { ...@@ -1405,7 +1470,7 @@ public abstract class CtClass {
* @see ClassPool#doPruning * @see ClassPool#doPruning
* *
* @see #toBytecode() * @see #toBytecode()
* @see #toClass() * @see #toClass(Class)
* @see #writeFile() * @see #writeFile()
* @see #instrument(CodeConverter) * @see #instrument(CodeConverter)
* @see #instrument(ExprEditor) * @see #instrument(ExprEditor)
......
...@@ -1526,7 +1526,7 @@ class CtClassType extends CtClass { ...@@ -1526,7 +1526,7 @@ class CtClassType extends CtClass {
ClassFile cf = getClassFile2(); ClassFile cf = getClassFile2();
ConstPool cp = cf.getConstPool(); ConstPool cp = cf.getConstPool();
List<MethodInfo> methods = cf.getMethods(); List<MethodInfo> methods = cf.getMethods();
for (MethodInfo minfo:methods) for (MethodInfo minfo: methods.toArray(new MethodInfo[methods.size()]))
converter.doit(this, minfo, cp); converter.doit(this, minfo, cp);
} }
...@@ -1537,7 +1537,7 @@ class CtClassType extends CtClass { ...@@ -1537,7 +1537,7 @@ class CtClassType extends CtClass {
checkModify(); checkModify();
ClassFile cf = getClassFile2(); ClassFile cf = getClassFile2();
List<MethodInfo> methods = cf.getMethods(); List<MethodInfo> methods = cf.getMethods();
for (MethodInfo minfo:methods) for (MethodInfo minfo: methods.toArray(new MethodInfo[methods.size()]))
editor.doit(this, minfo); editor.doit(this, minfo);
} }
......
...@@ -16,11 +16,12 @@ ...@@ -16,11 +16,12 @@
package javassist; package javassist;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import java.util.Arrays; import java.util.Arrays;
import java.util.Hashtable; import java.util.HashMap;
import java.util.Vector; import java.util.Vector;
import javassist.bytecode.ClassFile; import javassist.bytecode.ClassFile;
...@@ -138,7 +139,48 @@ import javassist.bytecode.ClassFile; ...@@ -138,7 +139,48 @@ import javassist.bytecode.ClassFile;
* @see javassist.Translator * @see javassist.Translator
*/ */
public class Loader extends ClassLoader { public class Loader extends ClassLoader {
private Hashtable<String,ClassLoader> notDefinedHere; // must be atomic.
/**
* A simpler class loader.
* This is a class loader that exposes the protected {@code defineClass()} method
* declared in {@code java.lang.ClassLoader}. It provides a method similar to
* {@code CtClass#toClass()}.
*
* <p>When loading a class, this class loader delegates the work to the
* parent class loader unless the loaded classes are explicitly given
* by {@link #invokeDefineClass(CtClass)}.
* Note that a class {@code Foo} loaded by this class loader is
* different from the class with the same name {@code Foo} but loaded by
* another class loader. This is Java's naming rule.
* </p>
*
* @since 3.24
*/
public static class Simple extends ClassLoader {
/**
* Constructs a class loader.
*/
public Simple() {}
/**
* Constructs a class loader.
* @param parent the parent class loader.
*/
public Simple(ClassLoader parent) {
super(parent);
}
/**
* Invokes the protected {@code defineClass()} in {@code ClassLoader}.
* It converts the given {@link CtClass} object into a {@code java.lang.Class} object.
*/
public Class<?> invokeDefineClass(CtClass cc) throws IOException, CannotCompileException {
byte[] code = cc.toBytecode();
return defineClass(cc.getName(), code, 0, code.length);
}
}
private HashMap<String,ClassLoader> notDefinedHere; // must be atomic.
private Vector<String> notDefinedPackages; // must be atomic. private Vector<String> notDefinedPackages; // must be atomic.
private ClassPool source; private ClassPool source;
private Translator translator; private Translator translator;
...@@ -186,7 +228,7 @@ public class Loader extends ClassLoader { ...@@ -186,7 +228,7 @@ public class Loader extends ClassLoader {
} }
private void init(ClassPool cp) { private void init(ClassPool cp) {
notDefinedHere = new Hashtable<String,ClassLoader>(); notDefinedHere = new HashMap<String,ClassLoader>();
notDefinedPackages = new Vector<String>(); notDefinedPackages = new Vector<String>();
source = cp; source = cp;
translator = null; translator = null;
......
...@@ -46,7 +46,7 @@ public class Modifier { ...@@ -46,7 +46,7 @@ public class Modifier {
public static final int ENUM = AccessFlag.ENUM; public static final int ENUM = AccessFlag.ENUM;
/** /**
* Returns true if the modifiers include the <tt>public</tt> * Returns true if the modifiers include the <code>public</code>
* modifier. * modifier.
*/ */
public static boolean isPublic(int mod) { public static boolean isPublic(int mod) {
...@@ -54,7 +54,7 @@ public class Modifier { ...@@ -54,7 +54,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>private</tt> * Returns true if the modifiers include the <code>private</code>
* modifier. * modifier.
*/ */
public static boolean isPrivate(int mod) { public static boolean isPrivate(int mod) {
...@@ -62,7 +62,7 @@ public class Modifier { ...@@ -62,7 +62,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>protected</tt> * Returns true if the modifiers include the <code>protected</code>
* modifier. * modifier.
*/ */
public static boolean isProtected(int mod) { public static boolean isProtected(int mod) {
...@@ -71,14 +71,14 @@ public class Modifier { ...@@ -71,14 +71,14 @@ public class Modifier {
/** /**
* Returns true if the modifiers do not include either * Returns true if the modifiers do not include either
* <tt>public</tt>, <tt>protected</tt>, or <tt>private</tt>. * <code>public</code>, <code>protected</code>, or <code>private</code>.
*/ */
public static boolean isPackage(int mod) { public static boolean isPackage(int mod) {
return (mod & (PUBLIC | PRIVATE | PROTECTED)) == 0; return (mod & (PUBLIC | PRIVATE | PROTECTED)) == 0;
} }
/** /**
* Returns true if the modifiers include the <tt>static</tt> * Returns true if the modifiers include the <code>static</code>
* modifier. * modifier.
*/ */
public static boolean isStatic(int mod) { public static boolean isStatic(int mod) {
...@@ -86,7 +86,7 @@ public class Modifier { ...@@ -86,7 +86,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>final</tt> * Returns true if the modifiers include the <code>final</code>
* modifier. * modifier.
*/ */
public static boolean isFinal(int mod) { public static boolean isFinal(int mod) {
...@@ -94,7 +94,7 @@ public class Modifier { ...@@ -94,7 +94,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>synchronized</tt> * Returns true if the modifiers include the <code>synchronized</code>
* modifier. * modifier.
*/ */
public static boolean isSynchronized(int mod) { public static boolean isSynchronized(int mod) {
...@@ -102,7 +102,7 @@ public class Modifier { ...@@ -102,7 +102,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>volatile</tt> * Returns true if the modifiers include the <code>volatile</code>
* modifier. * modifier.
*/ */
public static boolean isVolatile(int mod) { public static boolean isVolatile(int mod) {
...@@ -110,7 +110,7 @@ public class Modifier { ...@@ -110,7 +110,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>transient</tt> * Returns true if the modifiers include the <code>transient</code>
* modifier. * modifier.
*/ */
public static boolean isTransient(int mod) { public static boolean isTransient(int mod) {
...@@ -118,7 +118,7 @@ public class Modifier { ...@@ -118,7 +118,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>native</tt> * Returns true if the modifiers include the <code>native</code>
* modifier. * modifier.
*/ */
public static boolean isNative(int mod) { public static boolean isNative(int mod) {
...@@ -126,7 +126,7 @@ public class Modifier { ...@@ -126,7 +126,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>interface</tt> * Returns true if the modifiers include the <code>interface</code>
* modifier. * modifier.
*/ */
public static boolean isInterface(int mod) { public static boolean isInterface(int mod) {
...@@ -134,7 +134,7 @@ public class Modifier { ...@@ -134,7 +134,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>annotation</tt> * Returns true if the modifiers include the <code>annotation</code>
* modifier. * modifier.
* *
* @since 3.2 * @since 3.2
...@@ -144,7 +144,7 @@ public class Modifier { ...@@ -144,7 +144,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>enum</tt> * Returns true if the modifiers include the <code>enum</code>
* modifier. * modifier.
* *
* @since 3.2 * @since 3.2
...@@ -154,7 +154,7 @@ public class Modifier { ...@@ -154,7 +154,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>abstract</tt> * Returns true if the modifiers include the <code>abstract</code>
* modifier. * modifier.
*/ */
public static boolean isAbstract(int mod) { public static boolean isAbstract(int mod) {
...@@ -162,7 +162,7 @@ public class Modifier { ...@@ -162,7 +162,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>strictfp</tt> * Returns true if the modifiers include the <code>strictfp</code>
* modifier. * modifier.
*/ */
public static boolean isStrict(int mod) { public static boolean isStrict(int mod) {
...@@ -170,7 +170,7 @@ public class Modifier { ...@@ -170,7 +170,7 @@ public class Modifier {
} }
/** /**
* Returns true if the modifiers include the <tt>varargs</tt> * Returns true if the modifiers include the <code>varargs</code>
* (variable number of arguments) modifier. * (variable number of arguments) modifier.
*/ */
public static boolean isVarArgs(int mod) { public static boolean isVarArgs(int mod) {
......
...@@ -108,6 +108,10 @@ public class AttributeInfo { ...@@ -108,6 +108,10 @@ public class AttributeInfo {
/* Note that the names of Annotations attributes begin with 'R'. */ /* Note that the names of Annotations attributes begin with 'R'. */
if (nameStr.equals(MethodParametersAttribute.tag)) if (nameStr.equals(MethodParametersAttribute.tag))
return new MethodParametersAttribute(cp, name, in); return new MethodParametersAttribute(cp, name, in);
else if (nameStr.equals(NestHostAttribute.tag))
return new NestHostAttribute(cp, name, in);
else if (nameStr.equals(NestMembersAttribute.tag))
return new NestMembersAttribute(cp, name, in);
else if (nameStr.equals(AnnotationsAttribute.visibleTag) else if (nameStr.equals(AnnotationsAttribute.visibleTag)
|| nameStr.equals(AnnotationsAttribute.invisibleTag)) || nameStr.equals(AnnotationsAttribute.invisibleTag))
// RuntimeVisibleAnnotations or RuntimeInvisibleAnnotations // RuntimeVisibleAnnotations or RuntimeInvisibleAnnotations
......
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package javassist.bytecode;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.Map;
/**
* <code>NestHost_attribute</code>.
* It was introduced by JEP-181. See JVMS 4.7.28 for the specification.
*
* @since 3.24
*/
public class NestHostAttribute extends AttributeInfo {
/**
* The name of this attribute <code>"NestHost"</code>.
*/
public static final String tag = "NestHost";
NestHostAttribute(ConstPool cp, int n, DataInputStream in) throws IOException {
super(cp, n, in);
}
private NestHostAttribute(ConstPool cp, int hostIndex) {
super(cp, tag, new byte[2]);
ByteArray.write16bit(hostIndex, get(), 0);
}
/**
* Makes a copy. Class names are replaced according to the
* given <code>Map</code> object.
*
* @param newCp the constant pool table used by the new copy.
* @param classnames pairs of replaced and substituted
* class names.
*/
@Override
public AttributeInfo copy(ConstPool newCp, Map<String, String> classnames) {
int hostIndex = ByteArray.readU16bit(get(), 0);
int newHostIndex = getConstPool().copy(hostIndex, newCp, classnames);
return new NestHostAttribute(newCp, newHostIndex);
}
/**
* Returns <code>host_class_index</code>. The constant pool entry
* at this entry is a <code>CONSTANT_Class_info</code> structure.
* @return the value of <code>host_class_index</code>.
*/
public int hostClassIndex() {
return ByteArray.readU16bit(info, 0);
}
}