[Git][java-team/jboss-classfilewriter][master] 2 commits: Import Upstream version 1.2.4
Markus Koschany
gitlab at salsa.debian.org
Sun Feb 10 09:55:57 GMT 2019
Markus Koschany pushed to branch master at Debian Java Maintainers / jboss-classfilewriter
Commits:
78ffc413 by Markus Koschany at 2019-02-10T09:53:33Z
Import Upstream version 1.2.4
- - - - -
3d286e96 by Markus Koschany at 2019-02-10T09:53:37Z
Import Debian changes 1.2.4-1
jboss-classfilewriter (1.2.4-1) unstable; urgency=medium
* New upstream version 1.2.4
* Declare compliance with Debian Policy 4.3.0.
- - - - -
7 changed files:
- debian/changelog
- debian/control
- debian/copyright
- pom.xml
- + src/main/java/org/jboss/classfilewriter/ClassFactory.java
- src/main/java/org/jboss/classfilewriter/ClassFile.java
- + src/main/java/org/jboss/classfilewriter/DefaultClassFactory.java
Changes:
=====================================
debian/changelog
=====================================
@@ -1,3 +1,10 @@
+jboss-classfilewriter (1.2.4-1) unstable; urgency=medium
+
+ * New upstream version 1.2.4
+ * Declare compliance with Debian Policy 4.3.0.
+
+ -- Markus Koschany <apo at debian.org> Sat, 09 Feb 2019 12:43:29 +0100
+
jboss-classfilewriter (1.2.3-1) unstable; urgency=medium
* New upstream version 1.2.3.
=====================================
debian/control
=====================================
@@ -12,9 +12,9 @@ Build-Depends:
libmaven-javadoc-plugin-java,
libmaven-bundle-plugin-java,
maven-debian-helper (>= 1.5)
-Standards-Version: 4.1.5
-Vcs-Git: https://anonscm.debian.org/git/pkg-java/jboss-classfilewriter.git
-Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/jboss-classfilewriter.git
+Standards-Version: 4.3.0
+Vcs-Git: https://salsa.debian.org/java-team/jboss-classfilewriter.git
+Vcs-Browser: https://salsa.debian.org/java-team/jboss-classfilewriter
Homepage: https://github.com/jbossas/jboss-classfilewriter
Package: libjboss-classfilewriter-java
=====================================
debian/copyright
=====================================
@@ -3,11 +3,11 @@ Upstream-Name: classfilewriter
Source: https://github.com/jbossas/jboss-classfilewriter
Files: *
-Copyright: 2015-2018, Stuart Douglas <sdouglas at redhat.com>
+Copyright: 2015-2019, Stuart Douglas <sdouglas at redhat.com>
License: Apache-2.0
Files: debian/*
-Copyright: 2015-2018, Markus Koschany <apo at debian.org>
+Copyright: 2015-2019, Markus Koschany <apo at debian.org>
License: Apache-2.0
License: Apache-2.0
=====================================
pom.xml
=====================================
@@ -9,7 +9,7 @@
<groupId>org.jboss.classfilewriter</groupId>
<artifactId>jboss-classfilewriter</artifactId>
- <version>1.2.3.Final</version>
+ <version>1.2.4.Final</version>
<packaging>jar</packaging>
<description>A bytecode writer that creates .class files at runtime</description>
=====================================
src/main/java/org/jboss/classfilewriter/ClassFactory.java
=====================================
@@ -0,0 +1,62 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * Copyright 2019 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.classfilewriter;
+
+import java.security.ProtectionDomain;
+
+/**
+ * Class definition factory.
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ */
+public interface ClassFactory {
+
+ /**
+ * Converts an array of bytes into an instance of class <tt>Class</tt>.
+ *
+ * @param loader
+ * The classloader to be used for class definition.
+ *
+ * @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 in positions
+ * <tt>off</tt> through <tt>off+len-1</tt> should have the format
+ * of a valid class file as defined by
+ * <cite>The Java™ Virtual Machine Specification</cite>.
+ *
+ * @param off
+ * The start offset in <tt>b</tt> of the class data
+ *
+ * @param len
+ * The length of the class data
+ *
+ * @param protectionDomain
+ * The ProtectionDomain of the class
+ *
+ * @return The <tt>Class</tt> object that was created from the specified
+ * class data.
+ *
+ * @throws ClassFormatError
+ * If the data did not contain a valid class
+ */
+ Class<?> defineClass(ClassLoader loader, String name, byte[] b, int off, int len, ProtectionDomain protectionDomain) throws ClassFormatError;
+
+}
=====================================
src/main/java/org/jboss/classfilewriter/ClassFile.java
=====================================
@@ -19,14 +19,9 @@ package org.jboss.classfilewriter;
import java.io.IOException;
import java.lang.annotation.Annotation;
-import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays;
@@ -42,12 +37,8 @@ import org.jboss.classfilewriter.constpool.ConstPool;
import org.jboss.classfilewriter.util.ByteArrayDataOutputStream;
import org.jboss.classfilewriter.util.DescriptorUtils;
-import sun.misc.Unsafe;
-
/**
- *
* @author Stuart Douglas
- *
*/
public class ClassFile implements WritableEntry {
@@ -75,37 +66,69 @@ public class ClassFile implements WritableEntry {
private final ClassLoader classLoader;
+ private final ClassFactory classFactory;
+
+ @Deprecated
public ClassFile(String name, String superclass, String... interfaces) {
this(name, AccessFlag.of(AccessFlag.SUPER, AccessFlag.PUBLIC), superclass, null, interfaces);
}
+ @Deprecated
public ClassFile(String name, int accessFlags, String superclass, String... interfaces) {
this(name, accessFlags, superclass, null, interfaces);
}
+ @Deprecated
public ClassFile(String name, String superclass, ClassLoader classLoader, String... interfaces) {
this(name, AccessFlag.of(AccessFlag.SUPER, AccessFlag.PUBLIC), superclass, classLoader, interfaces);
}
+ @Deprecated
public ClassFile(String name, int accessFlags, String superclass, ClassLoader classLoader, String... interfaces) {
this(name, accessFlags, superclass, JavaVersions.JAVA_6, classLoader, interfaces);
}
+ @Deprecated
public ClassFile(String name, int accessFlags, String superclass, int version, ClassLoader classLoader, String... interfaces) {
if(version > JavaVersions.JAVA_6 && classLoader == null) {
throw new IllegalArgumentException("ClassLoader must be specified if version is greater than Java 6");
}
this.version = version;
this.classLoader = classLoader;
+ this.classFactory = null; // allowed to be null for backward compatibility reasons
this.name = name.replace('/', '.'); // store the name in . form
this.superclass = superclass;
this.accessFlags = accessFlags;
this.interfaces.addAll(Arrays.asList(interfaces));
- runtimeVisibleAnnotationsAttribute = new AnnotationsAttribute(AnnotationsAttribute.Type.RUNTIME_VISIBLE, constPool);
+ this.runtimeVisibleAnnotationsAttribute = new AnnotationsAttribute(AnnotationsAttribute.Type.RUNTIME_VISIBLE, constPool);
this.attributes.add(runtimeVisibleAnnotationsAttribute);
}
- private final static java.lang.reflect.Method defineClass1, defineClass2;
+ public ClassFile(String name, String superclass, ClassLoader classLoader, ClassFactory classFactory, String... interfaces) {
+ this(name, AccessFlag.of(AccessFlag.SUPER, AccessFlag.PUBLIC), superclass, classLoader, classFactory, interfaces);
+ }
+
+ public ClassFile(String name, int accessFlags, String superclass, ClassLoader classLoader, ClassFactory classFactory, String... interfaces) {
+ this(name, accessFlags, superclass, JavaVersions.JAVA_6, classLoader, classFactory, interfaces);
+ }
+
+ public ClassFile(String name, int accessFlags, String superclass, int version, ClassLoader classLoader, ClassFactory classFactory, String... interfaces) {
+ if(version > JavaVersions.JAVA_6 && classLoader == null) {
+ throw new IllegalArgumentException("ClassLoader must be specified if version is greater than Java 6");
+ }
+ if (classFactory == null) {
+ throw new IllegalArgumentException("ClassFactory must be specified");
+ }
+ this.version = version;
+ this.classLoader = classLoader;
+ this.classFactory = classFactory;
+ this.name = name.replace('/', '.'); // store the name in . form
+ this.superclass = superclass;
+ this.accessFlags = accessFlags;
+ this.interfaces.addAll(Arrays.asList(interfaces));
+ this.runtimeVisibleAnnotationsAttribute = new AnnotationsAttribute(AnnotationsAttribute.Type.RUNTIME_VISIBLE, constPool);
+ this.attributes.add(runtimeVisibleAnnotationsAttribute);
+ }
public void addInterface(String iface) {
this.interfaces.add(iface);
@@ -271,35 +294,9 @@ public class ClassFile implements WritableEntry {
}
private Class<?> defineInternal(ClassLoader loader, ProtectionDomain domain) {
- try {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- final int index = name.lastIndexOf('.');
- final String packageName;
- if(index == -1 ) {
- packageName = "";
- } else {
- packageName = name.substring(0, index);
- }
- RuntimePermission permission = new RuntimePermission("defineClassInPackage." + packageName);
- sm.checkPermission(permission);
- }
- byte[] b = toBytecode();
- java.lang.reflect.Method method;
- Object[] args;
- if (domain == null) {
- method = defineClass1;
- args = new Object[] { name.replace('/', '.'), b, Integer.valueOf(0), Integer.valueOf(b.length) };
- } else {
- method = defineClass2;
- args = new Object[] { name.replace('/', '.'), b, Integer.valueOf(0), Integer.valueOf(b.length), domain };
- }
- return (Class<?>) method.invoke(loader, args);
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ byte[] b = toBytecode();
+ final ClassFactory classFactory = this.classFactory == null ? DefaultClassFactory.INSTANCE : this.classFactory;
+ return classFactory.defineClass(loader, name, b, 0, b.length, domain);
}
public byte[] toBytecode() {
@@ -378,48 +375,4 @@ public class ClassFile implements WritableEntry {
return Collections.unmodifiableSet(methods);
}
- // Unsafe mechanics
-
- static {
- try {
- Method[] defineClassMethods = AccessController.doPrivileged(new PrivilegedExceptionAction<Method[]>() {
- public Method[] run() throws Exception {
- final sun.misc.Unsafe UNSAFE;
- final long overrideOffset;
- // first we need to grab Unsafe
- try {
- UNSAFE = getUnsafe();
- overrideOffset = UNSAFE.objectFieldOffset(AccessibleObject.class.getDeclaredField("override"));
- } catch (Exception e) {
- throw new Error(e);
- }
- // now we gain access to CL.defineClass methods
- Class<?> cl = ClassLoader.class;
- Method defClass1 = cl.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class,
- int.class });
- Method defClass2 = cl.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class,
- int.class, ProtectionDomain.class });
- // use Unsafe to crack open both CL.defineClass() methods (instead of using setAccessible())
- UNSAFE.putBoolean(defClass1, overrideOffset, true);
- UNSAFE.putBoolean(defClass2, overrideOffset, true);
- return new Method[]{defClass1, defClass2};
- }
- });
- // set methods to final fields
- defineClass1 = defineClassMethods[0];
- defineClass2 = defineClassMethods[1];
- } catch (PrivilegedActionException pae) {
- throw new RuntimeException("cannot initialize ClassFile", pae.getException());
- }
- }
-
- private static Unsafe getUnsafe() {
- try {
- Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
- theUnsafe.setAccessible(true);
- return (Unsafe) theUnsafe.get(null);
- } catch (Throwable t) {
- throw new RuntimeException("JDK did not allow accessing unsafe", t);
- }
- }
}
=====================================
src/main/java/org/jboss/classfilewriter/DefaultClassFactory.java
=====================================
@@ -0,0 +1,111 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ *
+ * Copyright 2019 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.classfilewriter;
+
+import sun.misc.Unsafe;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+
+/**
+ * Default class definition factory. This factory maintains backward compatibility
+ * but it doesn't work on JDK 12 and above where ClassLoader reflection magic is forbidden.
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ */
+final class DefaultClassFactory implements ClassFactory {
+
+ static final ClassFactory INSTANCE = new DefaultClassFactory();
+
+ private final java.lang.reflect.Method defineClass1, defineClass2;
+
+ private DefaultClassFactory() {
+ try {
+ Method[] defineClassMethods = AccessController.doPrivileged(new PrivilegedExceptionAction<Method[]>() {
+ public Method[] run() throws Exception {
+ final sun.misc.Unsafe UNSAFE;
+ final long overrideOffset;
+ // first we need to grab Unsafe
+ try {
+ Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
+ theUnsafe.setAccessible(true);
+ UNSAFE = (Unsafe) theUnsafe.get(null);
+ overrideOffset = UNSAFE.objectFieldOffset(AccessibleObject.class.getDeclaredField("override"));
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ // now we gain access to CL.defineClass methods
+ Class<?> cl = ClassLoader.class;
+ Method defClass1 = cl.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class,
+ int.class });
+ Method defClass2 = cl.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class,
+ int.class, ProtectionDomain.class });
+ // use Unsafe to crack open both CL.defineClass() methods (instead of using setAccessible())
+ UNSAFE.putBoolean(defClass1, overrideOffset, true);
+ UNSAFE.putBoolean(defClass2, overrideOffset, true);
+ return new Method[]{defClass1, defClass2};
+ }
+ });
+ // set methods to volatile fields
+ defineClass1 = defineClassMethods[0];
+ defineClass2 = defineClassMethods[1];
+ } catch (PrivilegedActionException pae) {
+ throw new RuntimeException("Cannot initialize DefaultClassFactory", pae.getException());
+ }
+ }
+
+ @Override
+ public Class<?> defineClass(final ClassLoader loader, final String name,
+ final byte[] b, final int off, final int len,
+ final ProtectionDomain domain) throws ClassFormatError {
+ try {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ final int index = name.lastIndexOf('.');
+ final String packageName;
+ if(index == -1 ) {
+ packageName = "";
+ } else {
+ packageName = name.substring(0, index);
+ }
+ RuntimePermission permission = new RuntimePermission("defineClassInPackage." + packageName);
+ sm.checkPermission(permission);
+ }
+ java.lang.reflect.Method method;
+ Object[] args;
+ if (domain == null) {
+ method = defineClass1;
+ args = new Object[]{name, b, 0, b.length};
+ } else {
+ method = defineClass2;
+ args = new Object[]{name, b, 0, b.length, domain};
+ }
+ return (Class<?>) method.invoke(loader, args);
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
View it on GitLab: https://salsa.debian.org/java-team/jboss-classfilewriter/compare/316f2d720bf9c4964139b5312db5b28c31f2310f...3d286e967f92977846e685c902c464c55dddec0b
--
View it on GitLab: https://salsa.debian.org/java-team/jboss-classfilewriter/compare/316f2d720bf9c4964139b5312db5b28c31f2310f...3d286e967f92977846e685c902c464c55dddec0b
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20190210/ea016581/attachment.html>
More information about the pkg-java-commits
mailing list