Closed anonyein closed 1 month ago
That is why this approach is discouraged. Rather use the method as a basis and inject a method handle, for example. What are you trying to achieve? Do you need to invoke any method?
That is why this approach is discouraged. Rather use the method as a basis and inject a method handle, for example. What are you trying to achieve? Do you need to invoke any method?
@raphw yes, need to invoke any method https://github.com/caoccao/JavetBuddy/blob/main/src/main/java/com/caoccao/javet/buddy/interop/proxy/BaseDynamicObjectHandler.java#L101 https://github.com/caoccao/JavetBuddy/blob/main/src/main/java/com/caoccao/javet/buddy/interop/proxy/DynamicObjectExtendHandler.java#L87
I want to make "intercept" method fit for Android
In this case you might be able to use Super.Instantiation.CONSTRUCTOR
? As long as the constructor does not do any method calls on the supplied objects, or any other input checks, this will work.
In this case you might be able to use
Super.Instantiation.CONSTRUCTOR
? As long as the constructor does not do any method calls on the supplied objects, or any other input checks, this will work.
W java.lang.IllegalStateException: size = 0
2024-10-21 18:28:17.548 9157-19242 System.err W at net.bytebuddy.matcher.FilterableList$AbstractBase.getOnly(FilterableList.java:139)
2024-10-21 18:28:17.550 9157-19242 System.err W at net.bytebuddy.implementation.auxiliary.TypeProxy$ForSuperMethodByConstructor.apply(TypeProxy.java:458)
2024-10-21 18:28:17.551 9157-19242 System.err W at net.bytebuddy.implementation.bind.MethodDelegationBinder$ParameterBinding$Anonymous.apply(MethodDelegationBinder.java:258)
2024-10-21 18:28:17.551 9157-19242 System.err W at net.bytebuddy.implementation.bytecode.StackManipulation$Compound.apply(StackManipulation.java:243)
2024-10-21 18:28:17.552 9157-19242 System.err W at net.bytebuddy.implementation.bind.MethodDelegationBinder$MethodBinding$Builder$Build.apply(MethodDelegationBinder.java:564)
2024-10-21 18:28:17.552 9157-19242 System.err W at net.bytebuddy.implementation.bytecode.StackManipulation$Compound.apply(StackManipulation.java:243)
2024-10-21 18:28:17.553 9157-19242 System.err W at net.bytebuddy.implementation.MethodDelegation$Appender.apply(MethodDelegation.java:1350)
2024-10-21 18:28:17.553 9157-19242 System.err W at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:732)
2024-10-21 18:28:17.554 9157-19242 System.err W at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:717)
2024-10-21 18:28:17.554 9157-19242 System.err W at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:624)
2024-10-21 18:28:17.555 9157-19242 System.err W at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:6077)
2024-10-21 18:28:17.555 9157-19242 System.err W at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2246)
2024-10-21 18:28:17.555 9157-19242 System.err W at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$UsingTypeWriter.make(DynamicType.java:4057)
2024-10-21 18:28:17.556 9157-19242 System.err W at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3741)
2024-10-21 18:28:17.556 9157-19242 System.err W at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:3993)
2024-10-21 18:28:17.557 9157-19242 System.err W at com.caoccao.javet.buddy.interop.proxy.BaseDynamicObjectAndroidHandler.getObjectClass(BaseDynamicObjectAndroidHandler.java:138)
2024-10-21 18:28:17.557 9157-19242 System.err W at com.caoccao.javet.buddy.interop.proxy.JavetReflectionObjectAndroidFactory.extend(JavetReflectionObjectAndroidFactory.java:103)
protected static final AndroidClassLoadingStrategy ANDROID_CLASS_LOADING_STRATEGY;
static {
File file = new File(JavetOSUtils.TEMP_DIRECTORY, RandomString.make());
if (!file.exists() && !file.isDirectory()) {
file.mkdirs();
}
ANDROID_CLASS_LOADING_STRATEGY = new AndroidClassLoadingStrategy.Wrapping(file);
}
protected Class<T> getObjectClass() {
DynamicType.Builder<T> builder = new ByteBuddy().subclass(type, CONSTRUCTOR_STRATEGY);
if (!AutoCloseable.class.isAssignableFrom(type)) {
builder = builder.implement(AutoCloseable.class);
}
try (DynamicType.Unloaded<T> unloadedType = builder
.method(ElementMatchers.isPublic())
.intercept(MethodDelegation.to(this))
.make()) {
return (Class<T>) unloadedType.load(getClass().getClassLoader(), ANDROID_CLASS_LOADING_STRATEGY).getLoaded();
}
}
You need to set the constructorParameters
property on the @Super
annotation for this. This property is needed to identify the constructor that you want to call. It needs to resemble the constructor parameter types of the relevant constructor.
You need to set the
constructorParameters
property on the@Super
annotation for this. This property is needed to identify the constructor that you want to call. It needs to resemble the constructor parameter types of the relevant constructor.
annotation cannot be variable, constructorParameters cannot be set. Are there other way to get super object?
That is right, but the proxy type cannot be variable either. What type do you use before @Super
?
That is right, but the proxy type cannot be variable either. What type do you use before
@Super
?
https://github.com/caoccao/JavetBuddy/blob/main/src/main/java/com/caoccao/javet/buddy/interop/proxy/DynamicObjectExtendHandler.java#L72 proxyType = TargetType.class
I see. I will have to add a dynamic resolver for this. That is not much work, so I can add it to the next version.
I see. I will have to add a dynamic resolver for this. That is not much work, so I can add it to the next version.
Thank you for your contribution and effort!
You can now specifiy a constructorResolver
property on the annotation to resolve the annotation dynamically.
java.lang.IllegalStateException: Cannot invoke Android dex file translation method
at net.bytebuddy.android.AndroidClassLoadingStrategy$DexProcessor$ForSdkCompiler$Dispatcher$ForApi26LevelCompatibleVm.translate(AndroidClassLoadingStrategy.java:647)
at net.bytebuddy.android.AndroidClassLoadingStrategy$DexProcessor$ForSdkCompiler$Conversion.register(AndroidClassLoadingStrategy.java:458)
at net.bytebuddy.android.AndroidClassLoadingStrategy.load(AndroidClassLoadingStrategy.java:164)
at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:101)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6367)
protected static final File Temp_Dir = getCurrentContext().getDir("libs", Context.MODE_PRIVATE);
protected static final AndroidClassLoadingStrategy ANDROID_CLASS_LOADING_STRATEGY = Temp_Dir.exists() && Temp_Dir.isDirectory() ?
new AndroidClassLoadingStrategy.Wrapping(Temp_Dir) :
Temp_Dir.mkdirs() ? new AndroidClassLoadingStrategy.Wrapping(Temp_Dir) : null;
DynamicType.Builder<T> builder = new ByteBuddy().subclass(type, CONSTRUCTOR_STRATEGY);
if (!AutoCloseable.class.isAssignableFrom(type)) {
builder = builder.implement(AutoCloseable.class);
}
try (DynamicType.Unloaded<T> unloadedType = builder
.method(ElementMatchers.isPublic())
.intercept(MethodDelegation.to(this))
.make()) {
return (Class<T>) unloadedType.load(getClass().getClassLoader(), ANDROID_CLASS_LOADING_STRATEGY).getLoaded();
}
The jar seems cannot be writen into "app_libs/" and only create "app_libs/oat/2QpqXOOB.jar.cur.prof" of 0KB on Android 11
Logcat:
2024-10-23 20:43:33.951 1378-2463 installd installd D Processing secondary dex path /data/user/0/com.xxxx.xxxx/app_libs/2QpqXOOB.jar
2024-10-23 20:43:33.952 1378-2463 installd installd D Processed secondary dex file /data/user/0/com.xxxx.xxxx/app_libs/2QpqXOOB.jar result=205
2024-10-23 20:43:33.953 5273-5405 OPDOM system_server D performDexOpt secondaryDex end for /data/user/0/com.xxxx.xxxx/app_libs/2QpqXOOB.jar sucessed: true
@Super(strategy = Super.Instantiation.UNSAFE, proxyType = TargetType.class) could not fit Android and how to get super object. Starting with Android 26 (Oreo, 8.0), Google began to gradually remove access to the internal sun class for reflection because it could cause security and compatibility issues.