GithubHelp home page GithubHelp logo

Comments (16)

xiaojinzi123 avatar xiaojinzi123 commented on May 25, 2024

你是不是把插件那个位置放的比其他插件下面了

from component.

Murmurl912 avatar Murmurl912 commented on May 25, 2024

用的新的Variant Api的transformClassesWith接口,这个是在所有的transform前执行的

from component.

xiaojinzi123 avatar xiaojinzi123 commented on May 25, 2024

代码给我看下吧

from component.

Murmurl912 avatar Murmurl912 commented on May 25, 2024

插件注册代码:
private fun config(project: Project) {
HostnameLog.info("config plugin for project: ${project.name}")
val androidComponents =
project.extensions.getByType(AndroidComponentsExtension::class.java)
androidComponents.onVariants { variant ->
if (unselect(variant)) {
return@onVariants
}
variant.transformClassesWith(
HostnameScanInstrument::class.java,
InstrumentationScope.PROJECT
) { params ->
params.ipv4AddressRegion.set(extension.ipadressRegionMap)
params.hostnameRegion.set(extension.hostnameRegionMap)
params.hostnameFilter.set(extension.hostnameFilterRules)
params.hostnameReportDir.set(outputDir)
params.enable.set(extension.scanHostname.get())
params.ignoredClassPrefix.set(extension.ignoreClassPrefix.get())
}
variant.transformClassesWith(
HostnameInstrument::class.java,
InstrumentationScope.PROJECT
) { params ->
params.removeRule.set(extension.removeHostnameRule)
params.enable.set(extension.removeHostname.get())
params.ignoredClassPrefix.set(extension.ignoreClassPrefix.get())
}
}
}

from component.

Murmurl912 avatar Murmurl912 commented on May 25, 2024

实现代码
abstract class HostnameInstrument: AsmClassVisitorFactory {

override fun createClassVisitor(
    classContext: ClassContext,
    nextClassVisitor: ClassVisitor
): ClassVisitor {
    val targets = config()[classContext.currentClassData.className]
    return if (targets != null) {
        HostnameLog.info("instrument on class ${classContext.currentClassData.className}")
        return HostnameClassVisitor(
            Opcodes.ASM7,
            nextClassVisitor,
            targets,
        )
    } else {
        HostnameLog.info("ignore instrument on class ${classContext.currentClassData.className}" +
                ", reason: instrument target is not configured")
        nextClassVisitor
    }
}

override fun isInstrumentable(classData: ClassData): Boolean {
    if (!parameters.get().enable.get()) {
        return false
    }
    if (isSignedClass(classData.className)) {
        HostnameLog.info("ignore class: ${classData.className}")
        return false
    }
    return config().containsKey(classData.className)
}

private fun isSignedClass(className: String): Boolean {
    for (prefix in parameters.get().ignoredClassPrefix.get()) {
        if (className.startsWith(prefix)) {
            return true
        }
    }
    return false
}

private fun factory() = HostnameRemoveFactory.instance(parameters.get())

private fun config() = factory().config()

}

from component.

Murmurl912 avatar Murmurl912 commented on May 25, 2024

项目里面还有其它插件使用了transform,都是在transformClassesWithComponentPlugin之后执行的。在我没有使用上面的新插件之前是可以编译通过的,加上了我的插件就不行。上面的插件只是做一些扫描硬编码域名的操作,会通过ClassVisitor来读取class文件。即使不在ClassVisitor中修改类,经过ClassReader和ClassWriter后,得到的class数据还是会发生变化。受AsmClassVisitorFactory 接口的限制,不能直接返回原始的class数据

from component.

xiaojinzi123 avatar xiaojinzi123 commented on May 25, 2024

意思就是你自己写了一个插件是吧. 那你 gradle 中应用插件的顺序的代码 也给我看下

from component.

Murmurl912 avatar Murmurl912 commented on May 25, 2024

我还是建议把compoent插件中transform读取jar的方式改一下JarFile jarFile = new JarFile(jarInput.getFile(), false);

from component.

xiaojinzi123 avatar xiaojinzi123 commented on May 25, 2024

image
你先把类似这个配置给我看下

还有就是我改不是问题. 那我得弄懂先, 改了会不会出其他问题

from component.

Murmurl912 avatar Murmurl912 commented on May 25, 2024

插件顺序大致如下
apply plugin: 'com.google.firebase.firebase-perf' // firebase性能监测,有个AsmClassesTransform会对一些类进行插桩
apply plugin: 'com.xiaojinzi.component.plugin
apply plugin: 其它插件
Transform的执行顺序
AsmClassesTransform - firebase插件
transformClassesWithComponentPluginForOverseaRelease - component插件
然后会出现:
Caused by: java.lang.SecurityException: SHA1 digest error for org/bouncycastle/LICENSE.class
at com.xiaojinzi.component.plugin.util.IOUtil.readAndWrite(IOUtil.java:22)
at com.xiaojinzi.component.plugin.ModifyASMUtilTransform.transform(ModifyASMUtilTransform.java:146)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:284)
at com.android.build.gradle.internal.profile.NoOpAnalyticsService.recordBlock(NoOpAnalyticsService.kt:72)
at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:242)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)

from component.

Murmurl912 avatar Murmurl912 commented on May 25, 2024

因为你构造JarFile默认把校验签名打开了,通过JarFile.getInputStream会检查签名的。下面是JarFile.getInputStream实现

/**
 * Returns an input stream for reading the contents of the specified
 * zip file entry.
 * @param ze the zip file entry
 * @return an input stream for reading the contents of the specified
 *         zip file entry
 * @throws ZipException if a zip file format error has occurred
 * @throws IOException if an I/O error has occurred
 * @throws SecurityException if any of the jar file entries
 *         are incorrectly signed.
 * @throws IllegalStateException
 *         may be thrown if the jar file has been closed
 */
public synchronized InputStream getInputStream(ZipEntry ze)
    throws IOException
{
    maybeInstantiateVerifier();
    if (jv == null) {
        return super.getInputStream(ze);
    }
    if (!jvInitialized) {
        initializeVerifier();
        jvInitialized = true;
        // could be set to null after a call to
        // initializeVerifier if we have nothing to
        // verify
        if (jv == null)
            return super.getInputStream(ze);
    }

    // wrap a verifier stream around the real stream
    return new JarVerifier.VerifierStream(
        getManifestFromReference(),
        ze instanceof JarFileEntry ?
        (JarEntry) ze : getJarEntry(ze.getName()),
        super.getInputStream(ze),
        jv);
}

from component.

xiaojinzi123 avatar xiaojinzi123 commented on May 25, 2024

apply plugin: 'com.google.firebase.firebase-perf' // firebase性能监测,有个AsmClassesTransform会对一些类进行插桩
apply plugin: 'com.xiaojinzi.component.plugin

这两句调换顺序, 把我的放前面. 你看下还出现吗?

apply plugin: 'com.xiaojinzi.component.plugin

这句就是放在 com.android.application 这个插件后面就行了

from component.

Murmurl912 avatar Murmurl912 commented on May 25, 2024

这样是没有问题的,我本地构建时候firebase-perf插件是没有启用的,可以编译通过。但是我还是建议把读取JarFile的地方改一下

from component.

xiaojinzi123 avatar xiaojinzi123 commented on May 25, 2024

那就是 firebase-pref 插件的启用导致的呗.

我那个插件本就生成一个 ASMUtil 这个类而已. 没有其他作用, 本来就放最前面就可以了.

那你把 firebase-perf 插件放我的后面不就完了

from component.

Murmurl912 avatar Murmurl912 commented on May 25, 2024

是可以这样改,但要是后面的人遇到这个问题,那不得怀疑好几天人生是不是自己的插件写错了

from component.

xiaojinzi123 avatar xiaojinzi123 commented on May 25, 2024

不瞒你说
因为插件顺序导致的问题已经不是一个两个了.
我怎么全部解决, 你这个我还能改代码, 很多其他的连问题都找不到. 我咋解决

我也只能在文档中强调这个事情了, 其他我做不了啥

而且你看看这个 issue 的最开始回复就是叫你看看顺序的问题, 你也没关注

from component.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.