esotericsoftware / reflectasm Goto Github PK
View Code? Open in Web Editor NEWHigh performance Java reflection
License: BSD 3-Clause "New" or "Revised" License
High performance Java reflection
License: BSD 3-Clause "New" or "Revised" License
From [email protected] on December 08, 2011 01:29:50
Please provide any additional information below.
I noticed that for field access every access gets promoted to Object by calling the valueOf methods on the primitive wrapper classes.
So you have provided an alternative to Field#set(Object, Object) and Field#get(Object).
Why don't you also provide primitive methods like setInt and getInt?
If the caller knows they will always be dealing with a certain primitive field these read methods would not need to allocate any object but just return the bits of the primitive. Wouldn't this help kyro be even a bit faster?
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=4
This library use asm 5.1 (at the moment) direclty. However as per http://asm.ow2.org/doc/faq.html#Q15, it suggest that
Tools and frameworks that are using ASM for bytecode processing (e.g. Hibernate, CGLIB, AspectWerkz) should repackage ASM code within their own name space. This can be automated with Jar Jar Links tool.
Here is a real issue caused by ASM library version conflict between sun's jersey and ReflectASM
ResultSet _rs=....
MethodAccess _rsAccess = MethodAccess.get(_rs.getClass());
_rsAccess.invoke(_rs, "getBlob", 1) //correct
_rsAccess.invoke(_rs, "getBlob", "id") //error
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
From [email protected] on May 30, 2012 19:19:54
Excellent work Nathan! This is not really an issue, but a possible enhancement.
I was very interested with MethodAccess. I would think a user would need to do project/domain specific type casting of objects. It would be helpful if this can allow the user to configure their own levels of casting.
Thanks.
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=5
From [email protected] on June 20, 2013 16:11:55
In some software I develop, Kryo is used for (de)serialisation.
With Sun JDK 1.6.0.45 or Icedtea 7, base classes have a ClassLoader that is null:
--8<--
import java.util.ArrayList;
public class test {
public static void main(String args[]) {
ArrayList foo = new ArrayList();
System.out.println("CL for JAL: " + foo.getClass().getClassLoader());
}
}
--8<--
returns:
CL for JAL: null
Thus, AccessClassLoader for such types will fail in loadClass() because getParent() returns null, resulting in a NullPointerException in NativeAccessorImpl.
To solve this, we should use the system class loader for classes without an attaced class loader.
The attached patch solves this problem as described.
Attachment: reflectasm-native.patch
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=15
It has bug fixes and some other projects have upgraded, so the version skew requires workarounds in build files that use frameworks which would otherwise mix asm versions.
java.lang.IllegalArgumentException: Unable to find non-private method: hello [class java.lang.String]
at com.esotericsoftware.reflectasm.MethodAccess.getIndex(MethodAccess.java:58)
at com.taobao.graphql.annotation.MethodResolver.<init>(MethodResolver.java:53)
at com.taobao.graphql.annotation.MethodResolver.<init>(MethodResolver.java:39)
at com.taobao.graphql.annotation.AnnotationToAST.getDataFetcher(AnnotationToAST.java:450)
at com.taobao.graphql.annotation.AnnotationToASTTest.getDataFetcherForMethod(AnnotationToASTTest.java:520)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
at com.esotericsoftware.reflectasm.MethodAccess#addDeclaredMethodsToList you skip the private one.
From [email protected] on June 13, 2012 15:51:05
I added this comment to a closed issue, by I clone it here as a new Improvement suggestion:
Instead of letting ClassWriter to autocompute MAXS, these are the right ones:
ClassWriter cw = new ClassWriter(0);
...
In the constructor: mv.visitMaxs(1, 1);
In insertSetObjectBytecode: mv.visitMaxs(4, 4);
In insertSetPrimitiveBytecode: mv.visitMaxs(4, 4);
In insertGetStringBytecode: mv.visitMaxs(4, 3);
In insertGetObjectBytecode: mv.visitMaxs(4, 3);
In insertGetPrimitiveBytecode: mv.visitMaxs(4, 3);
This gives a good boost to the start-up time for facades creation.
The same is already done in ConstructorAccess (and we could do the argument-counting for the MethodAccess)...
Regards,
Jesús
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=9
Is it available for android?
From [email protected] on March 07, 2011 22:03:54
What steps will reproduce the problem?
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=2
I believe this is needed for Java 8 compatibility, I'll try to do some testing this week to confirm or deny
Is it possible to change abstraction in way lib will become independent from Asm implementation?
I mean will it be possible to use AsmDex instead of original Asm library?
more info:
From [email protected] on November 01, 2013 16:24:43
When using constructor access to instantiate a package-private class (with either a declared package-private constructor or just the default constructor), I get the following exception:
java.lang.RuntimeException: Class cannot be created (missing no-arg constructor): com.esotericsoftware.reflectasm.ConstructorAccessTest$PackagePrivateClass
If my package-private class has declared a public constructor, it works. But I don't like telling people that they have to declare a no-arg, empty constructor if Java itself doesn't require it.
I'm attaching a patch that fixes this - it seems to just be a matter of calling getDeclaredConstructor rather than getConstructor. There's also a test case in the patch that demonstrates the issue (it fails before the getDeclaredConstructor fix, passes after it).
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=16
This project embeds 4.2 of ow2 asm, but that only supports Java 7:
http://websvn.ow2.org/filedetails.php?repname=asm&path=%2Ftags%2FASM_4_2%2Fsrc%2Forg%2Fobjectweb%2Fasm%2FClassReader.java
if (readShort(off + 6) > Opcodes.V1_7) {
An upgrade to 5.0 or greater will solve this problem. This also implies Apache Spark does not support Java 8 as it depends on this project.
Hi,
It seems that the artefact is not available in Maven Central.
Cheers
I try to do ConstructorAccess.get
,but it returned this error for me.
Could you support private members access right? Then, this framework will be more popular, and it's will be wilder used!
Using asm generates access code like :
public class XXXMethodAccess extends MethodAccess {
public Object invoke(Object paramObject, int methodIndex, Object[] paramArrayOfObject) {
XXX xxx = (XXX) paramObject;
try {
switch (methodIndex) {
case 0:
xxx.method0((String[]) paramArrayOfObject[0]);
return null;
case 1:
return xxx.method1((String) paramArrayOfObject[0]);
}
} catch (java.lang.IllegalAccessError e) {
Method method = methods.get(methodIndex);
method.setAccessible(true);
try {
return method.invoke(object, args);
} catch (Exception e) {
throw new IllegalStateException("invoke method error:" + method.getName(), e);
}
}
throw new IllegalArgumentException("Method not found: " + methodNames[paramInt]);
}
}
From [email protected] on June 12, 2012 21:28:10
Hello again,
FieldAccess has a member variable Field[] fields.
MethodAccess has a member variable Method[] methods.
In order both to:
I suggest to store only its names (String[] fieldNames, String[] methodNames).
This would break compatibility with current getFields and getMethods public methods (but I think in Kryo aren't used and in fact has little sense to an application usin reflectasm to obtain and use the java.lang.reflect.Field other than for private members (which are not cached in these arrays of FieldAccess and MethodAccess.
Regards,
Jesus
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=7
WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by com.esotericsoftware.reflectasm.AccessClassLoader (file:/C:/Users/Сергей/.m2/repository/com/esotericsoftware/reflectasm/1.11.7/reflectasm-1.11.7.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) WARNING: Please consider reporting this to the maintainers of com.esotericsoftware.reflectasm.AccessClassLoader 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
From [email protected] on August 15, 2012 10:39:52
A suggestion: in MethodAccess class,Can you add a method "public Object invoke (Object object, String methodName, Object... args, Class... paramTypes)",
When a class have more same name method to facilitate the call.
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=11
From [email protected] on February 06, 2013 10:02:22
If I understand your process, it is quite feasible to create an additional utility class e.g. MultiArgumentConstructorAccess which will be able to execute creation of objects using your approach, but with an explicit constructor.
e.g. MultiConstructorAccess MultiArgumentConstructorAccess.get(Class type, Constructor constructor)
multiConstructorAccess.newInstance(Object... param)
This is needed for applications where effect of calling the default constructor can't be "fixed" after creation by calling of the setters (example: SWT, more exactly my code I am trying to migrate to your approach: https://github.com/milanaleksic/swt-gui-transformer/blob/master/swt-gui-transformer-core/src/main/java/net/milanaleksic/guitransformer/converters/ObjectConverter.java#L319).
SWT blocks the changing of the style to maintain the UI and OS-calls consistency (), so I can't call afterwards the "setStyle(...)" - there is no setter of this kind to call at all across the widget hierarchy. See here for example: http://osdir.com/ml/ide.eclipse.platform.swt.devel/2006-09/msg00026.html
Have you considered migration to github/bitbucket for easier pull request handling, so I can try to do this by myself and then send to you for approval?
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=13
Do you see any issues with Android M runtime changes? I don't think you're overriding access checks, but I just wanted to make sure.
Thanks!
I got this warning when running Spring Boot on MacOS Mojave
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.esotericsoftware.reflectasm.AccessClassLoader (file:/Users/labs/.gradle/caches/modules-2/files-2.1/com.esotericsoftware/reflectasm/1.11.7/572a41b00181e9dd49e327675948b1d6301f9d48/reflectasm-1.11.7.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of com.esotericsoftware.reflectasm.AccessClassLoader
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
I use
Spring Boot 2.1.6.RELEASE
Java 11
Gradle dependencies
implementation 'com.graphql-java-kickstart:graphql-spring-boot-starter:5.6.0'
implementation 'com.graphql-java-kickstart:graphiql-spring-boot-starter:5.6.0'
implementation 'com.graphql-java-kickstart:graphql-java-tools:5.5.0'
The warning disappear when I remove the GraphQL Resolver from my project.
Why can private members not be accessed? Aren't you just adding a getter as java bytecode using ASM?
There are 2 methods:
Actual result:
MethodAccess.getIndex("getStrategyName") picks up the incorrect one.
Expected result:
Index of second definition must be retrieved if no parameters specified.
When instrumenting this example with our agent:
package main;
import com.esotericsoftware.reflectasm.MethodAccess;
public class Main {
public static void main(String[] args) {
StringBuilder obj = new StringBuilder("ff");
MethodAccess access = MethodAccess.get(obj.getClass());
System.out.println(access.invoke(obj, "toString"));
}
}
I am getting this error when our ASM dependency (6.1.1) tries to parse the generated subclass bytecode reflectasm/java/lang/StringBuilderMethodAccess
:
<< 2018-05-25 10:45:06.643 ERROR 1 Error found instrumenting class reflectasm/java/lang/StringBuilderMethodAccess
<< java.lang.IllegalArgumentException
<< at org.objectweb.asm.ClassReader.readVerificationTypeInfo(ClassReader.java:3138)
<< at org.objectweb.asm.ClassReader.readStackMapFrame(ClassReader.java:3065)
<< at org.objectweb.asm.ClassReader.readCode(ClassReader.java:1812)
<< at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1238)
<< at org.objectweb.asm.ClassReader.accept(ClassReader.java:631)
<< at org.objectweb.asm.ClassReader.accept(ClassReader.java:355)
<< at io.shiftleft.bctrace.asm.Transformer.transform(Transformer.java:128)
<< at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
<< at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
<< at java.lang.ClassLoader.defineClass1(Native Method)
<< at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
<< at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
<< at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
<< at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
<< at java.lang.reflect.Method.invoke(Method.java:498)
<< at com.esotericsoftware.reflectasm.AccessClassLoader.defineClass(AccessClassLoader.java:85)
<< at com.esotericsoftware.reflectasm.MethodAccess.get(MethodAccess.java:254)
<< at main.Main.main(Main.java:9)
After debugging this I see the reason is an invalid value of 12 (ITEM_ASM_SHORT
) for a verification_type_info
of a stack map frame.
I am not sure yet if this is caused by your implementation, or by the ASM dependency your are using, but this bytecode is not valid, and we are suspecting it's one of the reasons for SIGSEGV
JVM crashes we are experiencing in some environments.
/******************************************************************************
* Inspired by https://github.com/EsotericSoftware/reflectasm
* the main idea is to take away introspection from ReflectASM
*
* You must obtain reflection member (Constructor,Method or Field)
* yourself then pass it to FastReflection.of() method to obtain
* code generated access-object...
*
* Also (since it operate per-member basis) it takes away ugly switches
* into generated bytecode, supports parametrized constructors and
* static fields/members...
*/
EntityMethodAccess is created by ReflectASM,I think it should implements Seriablizable
java.io.NotSerializableException: com.juno.java.frame.core.model.EntityMethodAccess
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:440)
at net.sf.ehcache.Element.writeObject(Element.java:867)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1495)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at net.sf.ehcache.util.MemoryEfficientByteArrayOutputStream.serialize(MemoryEfficientByteArrayOutputStream.java:97)
at net.sf.ehcache.store.disk.DiskStorageFactory.serializeElement(DiskStorageFactory.java:399)
at net.sf.ehcache.store.disk.DiskStorageFactory.write(DiskStorageFactory.java:381)
at net.sf.ehcache.store.disk.DiskStorageFactory$DiskWriteTask.call(DiskStorageFactory.java:473)
at net.sf.ehcache.store.disk.DiskStorageFactory$PersistentDiskWriteTask.call(DiskStorageFactory.java:1067)
at net.sf.ehcache.store.disk.DiskStorageFactory$IndexWriteTask.call(DiskStorageFactory.java:1104)
at net.sf.ehcache.store.disk.DiskStorageFactory.unbind(DiskStorageFactory.java:917)
at net.sf.ehcache.store.disk.DiskStore.dispose(DiskStore.java:664)
at net.sf.ehcache.store.CacheStore.dispose(CacheStore.java:327)
at net.sf.ehcache.Cache.dispose(Cache.java:2521)
at net.sf.ehcache.CacheManager.shutdown(CacheManager.java:1523)
at org.springframework.cache.ehcache.EhCacheManagerFactoryBean.destroy(EhCacheManagerFactoryBean.java:190)
at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:262)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:972)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:979)
at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1006)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:982)
at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:901)
From [email protected] on November 27, 2012 05:15:45
ASM guys suggest repackaging your asm jar files with jarjar if you want to use different versions of asm in your project. In fact, spring team repackaged asm into their own package name to avoid potential conflict.
In my project, I have two repackaged versions of asm and a standard one which is 3.1. If I use the latest reflectasm I have to put asm 4.0 into my class path which will conflict.
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=12
From [email protected] on December 24, 2010 03:43:09
What steps will reproduce the problem?
1.FieldAccess.get method invoked in servlet init method throws NoClassDefFoundError exception in Tomcat 6.0 with JDK6
2.
3.
What is the expected output? What do you see instead?
java.lang.NoClassDefFoundError: com/esotericsoftware/reflectasm/FieldAccess
java.lang.ClassLoader.defineClass1(Native Method)
java.lang.ClassLoader.defineClass(ClassLoader.java:621)
java.lang.ClassLoader.defineClass(ClassLoader.java:466)
com.esotericsoftware.reflectasm.AccessClassLoader.defineClass(AccessClassLoader.java:14)
com.esotericsoftware.reflectasm.FieldAccess.get(FieldAccess.java:195)
TestServlet.init(TestServlet.java:27)
javax.servlet.GenericServlet.init(GenericServlet.java:212)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:619)
What version of the product are you using? On what operating system?
reflectasm 0.8, Tomcat 6.0, JDK1.6
Please provide any additional information below.
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=1
The reflected classes are stored in an array whose ordering is changed on code reload(JRebel). The API seems to rely on this ordering.
This causes ArrayIndexOutOfBoundsException(class at index 6, length also 6) or undefined behaviour(want to load class a, get b instead).
Updating indices on array change should fix the problem.
From [email protected] on October 12, 2011 04:03:19
What steps will reproduce the problem?
I wasn't able to come up with exact steps to reproduce, but it always failed in my large application.
What is the expected output? What do you see instead?
stack too large exception
What version of the product are you using? On what operating system?
Latest. OS X.
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-383, mixed mode)
Please provide any additional information below.
This patch seems to fix it:
Index: MethodAccess.java
===================================================================
--- MethodAccess.java (revision 18)
+++ MethodAccess.java (working copy)
@@ -44,7 +44,7 @@
String accessClassNameInternal = accessClassName.replace('.', '/');
String classNameInternal = className.replace('.', '/');
ClassWriter cw = new ClassWriter(0);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
MethodVisitor mv;
cw.visit(V1_1, ACC_PUBLIC, accessClassNameInternal, null, "com/esotericsoftware/reflectasm/MethodAccess", null);
{
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=3
From [email protected] on June 12, 2012 16:24:29
Current version of AccessClassLoader.get(Class):
static AccessClassLoader get (Class type) {
ClassLoader parent = type.getClassLoader();
for (int i = 0, n = accessClassLoaders.size(); i < n; i++) {
AccessClassLoader accessClassLoader = accessClassLoaders.get(i);
if (accessClassLoader.getParent() == parent) return accessClassLoader;
}
return new AccessClassLoader(parent);
}
I think it shoud be something like this (and synchronized or double-checked with volatile):
static synchronized AccessClassLoader get (Class type) {
ClassLoader parent = type.getClassLoader();
for (int i = 0, n = accessClassLoaders.size(); i < n; i++) {
AccessClassLoader accessClassLoader = accessClassLoaders.get(i);
if (accessClassLoader.getParent() == parent) return accessClassLoader;
}
AccessClassLoader newClassLoader = new AccessClassLoader(parent);
accessClassLoaders.add(newClassLoader);
return newClassLoader;
}
Regards
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=6
From [email protected] on June 13, 2012 16:00:04
The member variable "accessClassLoaders" must be declared as final, ot the synchronization block is broken in the JMM.
By the way, other smaaaal improvement in method defineClass: replace
(....) new Integer(0), new Integer(bytes.length)});
By:
(....) Integer.valueOf(0), Integer.valueOf(bytes.length)});
Cheers!
Jesus
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=10
The library defines the "Import-Package: org.objectweb.asm;version="[5.1,6)"" MANIFEST.MF header even though the asm library is shaded and therefore no import is needed.
seems like reflection outperforms ReflectASM >8[]
private static Method getDefineClassMethod() throws Exception {
// DCL on volatile
if (defineClassMethod==null) {
synchronized(accessClassLoaders) {
defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] {String.class, byte[].class, int.class,
int.class, ProtectionDomain.class});
try {
defineClassMethod.setAccessible(true);
}
catch (Exception ignored) {
}
}
}
return defineClassMethod;
}
When Thread 1 assign a value to defineClassMethod and leave the critical section, then Thread 2 may assign a new value to defineClassMethod.
Maybe should check defineClassMethod==null inside synchronized(accessClassLoaders) code block too to avoid this issue and complete the DCL.
the {Constructor,Field,Method}Access classes first delegate to AccessClassLoader when an accessor is requested and the ACL in turn delegates to the parent classloader, and generates the accessor if it is not found. ie, it uses the parent class loader as a cache
this can be an expensive operation, eg if the parent classloader is a network loader, and as such is not a very good cache
i submitted a pull request (#51) that works around this by only querying the parent class loader if the accessor has been generated, but it hasn't been commented on or accepted
an alternative would be to identify the accessor classes in the parent classloader and throw an exception there (rather than query the network). however, i don't see a reasonably safe means of identifying generated class names (the naming scheme involves appending "{Constructor,Field,Method}Access" which could well show up in a user class name). i'd be willing to submit a pull request that used more-easily-filtered names if that approach would be preferred (eg EsotericSoftwareOriginalNameFieldAccess), though i prefer the former deterministic approach
http://mvnrepository.com/artifact/com.esotericsoftware/reflectasm
Only 1.11.3 is listed here.
From [email protected] on November 06, 2013 20:17:49
When calling MethodAccess.get() with an interface class as argument, it runs into null pointer, because AnyInterface.class.getSuperclass() returns null.
Example:
MethodAccess myAcess = MethodAccess.get(MyInterface.class);
==>
java.lang.NullPointerException
at com.esotericsoftware.reflectasm.MethodAccess.get(MethodAccess.java:53)
...
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=17
MethodAccess now only stores the parameter classes of methods, but sometimes we need to get the generic parameter types of a method. Is it possible to add an array in the MethodAccess to store these generic parameter types?
From [email protected] on June 13, 2012 15:47:40
Look at the attachment with my proposal for adding a "T newInstance (Object enclosingInstance)" method, allowing inner classes instantiation :-)
So caller could do:
if (constructorAccess.isNonStaticMemberClass()) {
newInstance = constructorAccess.newInstance(enclosingInstance);
}
else {
newInstance = constructorAccess.newInstance();
}
Regards!
Attachment: ConstructorAccess.java
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=8
From [email protected] on March 25, 2013 11:04:11
The access classes defined by AccessClassLoader don't have proper ProtectionDomain. It causes issue when the reflectasm is used in the environment with SecurityManger and customer security policy. The access will be denied when the operated class need to access restricted resource.
The exception likes
INFO | jvm 1 | 2013/03/22 05:09:09 | java.security.AccessControlException: access denied ("java.io.FilePermission":\bb_content\locale\en_US\plugins\cs_locales.properties" "read")
INFO | jvm 1 | 2013/03/22 05:09:09 | at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
INFO | jvm 1 | 2013/03/22 05:09:09 | at java.security.AccessController.checkPermission(AccessController.java:560)
INFO | jvm 1 | 2013/03/22 05:09:09 | at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
INFO | jvm 1 | 2013/03/22 05:09:09 | at java.lang.SecurityManager.checkRead(SecurityManager.java:888)
INFO | jvm 1 | 2013/03/22 05:09:09 | at java.io.File.exists(File.java:770)
INFO | jvm 1 | 2013/03/22 05:09:09 | at blackboard.redis.TestPermission.run(TestPermission.java:11)
INFO | jvm 1 | 2013/03/22 05:09:09 | at blackboard.redis.TestPermissionMethodAccess.invoke(Unknown Source)
INFO | jvm 1 | 2013/03/22 05:09:09 | at com.esotericsoftware.reflectasm.MethodAccess.invoke(MethodAccess.java:25)
I'm using the latest version 1.07. I think that would be great if the generated access classes have the same ProtectionDomain with reflectasm.
Here is a patch based on 1.07.
--- AccessClassLoader.java (revision 49)
+++ AccessClassLoader.java (working copy)
@@ -2,6 +2,7 @@
package com.esotericsoftware.reflectasm;
import java.lang.reflect.Method;
+import java.security.ProtectionDomain;
import java.util.ArrayList;
class AccessClassLoader extends ClassLoader {
@@ -37,9 +38,9 @@
try {
// Attempt to load the access class in the same loader, which makes protected and default access members accessible.
Method method = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] {String.class, byte[].class, int.class,
int.class});
int.class, ProtectionDomain.class});
method.setAccessible(true);
return (Class)method.invoke(getParent(), new Object[] {name, bytes, Integer.valueOf(0), Integer.valueOf(bytes.length)});
return (Class)method.invoke(getParent(), new Object[] {name, bytes, Integer.valueOf(0), Integer.valueOf(bytes.length), getClass().getProtectionDomain()});
} catch (Exception ignored) {
}
return defineClass(name, bytes, 0, bytes.length);
Original issue: http://code.google.com/p/reflectasm/issues/detail?id=14
I found reflectasm
is not as fast as original jdk newInstance
, please see my test code
@Test
public void test_batch_newInstance_use_original_jdk(){
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
try {
ArtisanCouponModel.class.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.printf("Original jdk newInstance took time: %d(ms)%n",System.currentTimeMillis() - start);
}
Original jdk newInstance took time: 1(ms)
public void test_batch_newInstance_use_reflectasm(){
long start = System.currentTimeMillis();
ConstructorAccess<ArtisanCouponModel> access = ConstructorAccess.get(ArtisanCouponModel.class);
for (int i = 0; i < 1000; i++) {
access.newInstance();
}
System.out.printf("reflectasm newInstance took time: %d(ms)%n",System.currentTimeMillis() - start);
}
reflectasm newInstance took time: 16(ms)
The java version is
/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java
Currently reflectasm releases a JAR with a transitive dependency on ASM as
<groupId>com.esotericsoftware</groupId>
<artifactId>reflectasm</artifactId>
<version>1.10.0</version>
and a JAR with ASM bundled and relocated as
<groupId>com.esotericsoftware</groupId>
<artifactId>reflectasm</artifactId>
<version>1.10.0</version>
<classifier>shaded</classifier>
This causes some minor headaches such as the shaded JAR sharing a POM with the original JAR so it still has a transitive dependency on ASM which needs to be excluded. But more importantly, using a classifier changes the maven coordinates. This makes it possible to have both the normal and shaded JAR end up in your dependency tree. It also makes it impossible to use Maven's dependencyManagement
facility to control whether you want the normal or shaded JAR.
I think it would be better to distinguish the shaded JAR with a version suffix, something like 1.10.0-shaded
. By using the same maven coordinates, you're guaranteed that you only have either the normal or shaded JAR in your dependency tree, and it's easy to control which one you get through dependency management without needing to resort to exclusions and other hackery
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.