Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android sun.reflect.ReflectionFactory no found #1720

Closed
anonyein opened this issue Oct 20, 2024 · 12 comments
Closed

Android sun.reflect.ReflectionFactory no found #1720

anonyein opened this issue Oct 20, 2024 · 12 comments
Assignees
Milestone

Comments

@anonyein
Copy link

anonyein commented Oct 20, 2024

@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.

@raphw
Copy link
Owner

raphw commented Oct 20, 2024

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 raphw self-assigned this Oct 20, 2024
@raphw raphw added the question label Oct 20, 2024
@raphw raphw added this to the 1.15.3 milestone Oct 20, 2024
@anonyein
Copy link
Author

anonyein commented Oct 21, 2024

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

@raphw
Copy link
Owner

raphw commented Oct 21, 2024

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.

@anonyein
Copy link
Author

anonyein commented Oct 21, 2024

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();
        }
    }

@raphw
Copy link
Owner

raphw commented Oct 21, 2024

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.

@anonyein
Copy link
Author

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?

@raphw
Copy link
Owner

raphw commented Oct 22, 2024

That is right, but the proxy type cannot be variable either. What type do you use before @Super?

@anonyein
Copy link
Author

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

@raphw
Copy link
Owner

raphw commented Oct 22, 2024

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.

@anonyein
Copy link
Author

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!

@raphw
Copy link
Owner

raphw commented Oct 22, 2024

You can now specifiy a constructorResolver property on the annotation to resolve the annotation dynamically.

@anonyein
Copy link
Author

anonyein commented Oct 23, 2024

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

#1722

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants