混淆问题在IntelliJ插件开发中

huangapple go评论87阅读模式
英文:

proguard issue in intellij plugin development

问题

我正在尝试使用 ProGuard 来混淆我的 IntelliJ 插件。

我正在向 IntelliJ 添加一些内部 fileTemplates 以用于创建新文件。<RelatedTemplateName> 是我添加到 resources/fileTemplates/internal/<RelatedTemplateName>.ft 文件中的文件名。

到目前为止,一切都很好,除了...

在混淆后的插件中:
IntelliJ 代码无法在我的插件内找到某些资源文件。

在非混淆的插件中:
一切正常运作。

我曾经以为 ProGuard 改变了我的资源文件,但根据这个链接,我不认为任何资源文件被改变了,因为我没有将这些选项添加到我的 proguard.pro 文件中。

有人可以帮助我找出这个问题的根本原因吗?谢谢。

是不是因为 ProGuard 改变了与此相关的其他类?

其他相关信息如下:

异常信息:

java.lang.Throwable: Template not found: <RelatedTemplateName>
	at com.intellij.openapi.diagnostic.Logger.error(Logger.java:145)
	at com.intellij.ide.fileTemplates.impl.FileTemplateManagerImpl.getTemplateFromManager(FileTemplateManagerImpl.java:294)
	at com.intellij.ide.fileTemplates.impl.FileTemplateManagerImpl.getJ2eeTemplate(FileTemplateManagerImpl.java:279)
	at com.intellij.ide.fileTemplates.impl.FileTemplateManagerImpl.getInternalTemplate(FileTemplateManagerImpl.java:242)
	at XXX.XXX.XXX.createNewFile(MyNewFileAction.java:104)

我的 ProGuard 配置:

在 build.gradle 文件中的相关部分:

def getIDEAPath(){
    if(intellij.localPath!=null && !intellij.localPath.isEmpty()){
        return intellij.localPath
    }
    def ideTempPath = file("$gradle.gradleUserHomeDir/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/ideaIC/$intellij.version")
    def ideBasePath = ideTempPath;
    ideTempPath.traverse([maxDepth: 2, type: groovy.io.FileType.DIRECTORIES]) {
        it ->
            if (it.absolutePath.contains("lib")) {
                ideBasePath = file(it.absolutePath);
            };
    }
    return ideBasePath.parent
}

task myProguardTask(type: proguard.gradle.ProGuardTask, dependsOn: jar) {
    printmapping "build/mapping.txt"
    configuration 'proguard.pro'
    // 其他配置...
}

在我的 proguard.pro 文件中的相关部分:

-adaptresourcefilecontents 被注释掉

-target 1.8
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
##-adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF
-verbose

-keepclassmember class * {
    public <init>(***);
}

# 其他配置...
英文:

I am trying to use ProGuard for obfuscation of my intellij plugin.

I am adding some internal fileTemplates to IntelliJ for creating new files. &lt;RelatedTemplateName&gt; is the filename I added to resources/fileTemplates/internal/&lt;RelatedTemplateName&gt;.ft

So far so good, except ...

In Obfuscated plugin:
IntelliJ code couldn't find some resource file inside my plugin.

In non-obfuscated plugin:
everything works fine.

I once thought proguard changed my resource files, but I don't think any resource file was changed according to this link
, because I don't have such options added to my proguard.pro file

Would anyone help me to find out the root cause of this issue? Thanks

Is it because of proguard changed some other classes related to this?

Other related infomation below

Exception

java.lang.Throwable: Template not found: &lt;RelatedTemplateName&gt;
	at com.intellij.openapi.diagnostic.Logger.error(Logger.java:145)
	at com.intellij.ide.fileTemplates.impl.FileTemplateManagerImpl.getTemplateFromManager(FileTemplateManagerImpl.java:294)
	at com.intellij.ide.fileTemplates.impl.FileTemplateManagerImpl.getJ2eeTemplate(FileTemplateManagerImpl.java:279)
	at com.intellij.ide.fileTemplates.impl.FileTemplateManagerImpl.getInternalTemplate(FileTemplateManagerImpl.java:242)
	at XXX.XXX.XXX.createNewFile(MyNewFileAction.java:104)

my proguard configuration:

related part of build.gradle file:

def getIDEAPath(){
    if(intellij.localPath!=null &amp;&amp; !intellij.localPath.isEmpty()){
        return intellij.localPath
    }
    def ideTempPath = file(&quot;$gradle.gradleUserHomeDir/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/ideaIC/$intellij.version&quot;)
    def ideBasePath = ideTempPath;
    ideTempPath.traverse([maxDepth: 2, type: groovy.io.FileType.DIRECTORIES]) {
        it -&gt;
            if (it.absolutePath.contains(&quot;lib&quot;)) {
                ideBasePath = file(it.absolutePath);
            };
    }
    return ideBasePath.parent
}


task myProguardTask(type: proguard.gradle.ProGuardTask, dependsOn: jar) {
    printmapping &quot;build/mapping.txt&quot;
    configuration &#39;proguard.pro&#39;
    // Automatically handle the Java version of this build.
    if (System.getProperty(&#39;java.version&#39;).startsWith(&#39;1.&#39;)) {
        // Before Java 9, the runtime classes were packaged in a single jar file.
        libraryjars &quot;${System.getProperty(&#39;java.home&#39;)}/lib/rt.jar&quot;
    } else {
        // As of Java 9, the runtime classes are packaged in modular jmod files.
        libraryjars &quot;${System.getProperty(&#39;java.home&#39;)}/jmods/java.base.jmod&quot;, jarfilter: &#39;!**.jar&#39;, filter: &#39;!module-info.class&#39;
        libraryjars &quot;${System.getProperty(&#39;java.home&#39;)}/jmods/java.sql.jmod&quot;, jarfilter: &#39;!**.jar&#39;, filter: &#39;!module-info.class&#39;
        //libraryjars &quot;${System.getProperty(&#39;java.home&#39;)}/jmods/.....&quot;
    }
    def ideaPath = getIDEAPath()
    libraryjars fileTree(&quot;$ideaPath/plugins/java/lib&quot;).filter { !it.name.startsWith(&quot;debugger&quot;) }.collect()
    libraryjars files(&quot;$ideaPath/lib&quot;)
    libraryjars files(configurations.compile.collect())

    def original = jar.archiveFile.get().asFile
    def obfuscated = new File(original.parent, &quot;obfuscated.jar&quot;)

    injars original
    outjars file(obfuscated.path)
}

prepareSandbox.dependsOn(myProguardTask)

prepareSandbox.doFirst {
    def original = jar.archiveFile.get().asFile
    def obfuscated = new File(original.parent, &quot;obfuscated.jar&quot;)
    if (original.exists() &amp;&amp; obfuscated.exists()) {
        original.delete()
        obfuscated.renameTo(original)
    } else {
        println &quot;error: some file does not exist, plugin file not obfuscated&quot;
    }
}

related part of my proguard.pro file:

-adaptresourcefilecontents is commented out

-target 1.8
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
##-adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF
-verbose

-keepclassmember class * {
    public &lt;init&gt;(***);
}

# Also keep - Enumerations. Keep the special static methods that are required in
# enumeration classes.
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

# Also keep - Swing UI L&amp;F. Keep all extensions of javax.swing.plaf.ComponentUI,
# along with the special &#39;createUI&#39; method.
-keep class * extends javax.swing.plaf.ComponentUI {
public static javax.swing.plaf.ComponentUI createUI(javax.swing.JComponent);
}

-keepclassmembers class * implements java.io.Serializable {
        static final long serialVersionUID;
        private static final java.io.ObjectStreamField[] serialPersistentFields;
        !static !transient &lt;fields&gt;;
        !private &lt;fields&gt;;
        !private &lt;methods&gt;;
        private void writeObject(java.io.ObjectOutputStream);
        private void readObject(java.io.ObjectInputStream);
        java.lang.Object writeReplace();
        java.lang.Object readResolve();
    }

答案1

得分: 0

噢,我终于找到了解决方法。所以最终,ProGuard没有改变我的资源文件,但它确实改变了我的资源文件夹。

解决方法:

我在proguard.pro文件中添加了-keepdirectories,以保留jar文件内的所有目录。

以下是来自官方网站的引用:

MissingResourceException或NullPointerException

处理后的代码可能无法找到某些资源文件。ProGuard只是简单地将资源文件从输入jar复制到输出jar中。它们的名称和内容保持不变,除非您指定了-adaptresourcefilenames和/或-adaptresourcefilecontents选项。此外,jar文件中的目录条目不会被复制,除非您指定了-keepdirectories选项。请注意,Sun不建议对目录调用Class.getResource()方法(Sun Bug #4761949)。

这是关于-keepdirectories链接

引用:

默认情况下,目录条目会被移除。

英文:

Oh, I finally find out the solution to this. So in the end , proguard did not change my resource files,but it did change my resource folder

Solution:

I added -keepdirectories to proguard.pro file to keep all the directories inside jar file.

Here is the quote from official website

> MissingResourceException or NullPointerException
>
> Your processed code may be unable to find some resource files.
> ProGuard simply copies resource files over from the input jars to the
> output jars. Their names and contents remain unchanged, unless you
> specify the options-adaptresourcefilenames
> and/or-adaptresourcefilecontents. Furthermore, directory entries in
> jar files aren't copied, unless you specify the option
> -keepdirectories. Note that Sun advises against calling Class.getResource() for directories (Sun Bug
> #4761949](http://bugs.sun.com/view_bug.do?bug_id=4761949)).

here is the link for -keepdirectories

quote
> By default, directory entries are removed.

huangapple
  • 本文由 发表于 2020年8月15日 18:00:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/63424774.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定