英文:
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. <RelatedTemplateName>
is the filename I added to resources/fileTemplates/internal/<RelatedTemplateName>.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: <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)
my proguard configuration:
related part of build.gradle file:
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'
// Automatically handle the Java version of this build.
if (System.getProperty('java.version').startsWith('1.')) {
// Before Java 9, the runtime classes were packaged in a single jar file.
libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
} else {
// As of Java 9, the runtime classes are packaged in modular jmod files.
libraryjars "${System.getProperty('java.home')}/jmods/java.base.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
libraryjars "${System.getProperty('java.home')}/jmods/java.sql.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
//libraryjars "${System.getProperty('java.home')}/jmods/....."
}
def ideaPath = getIDEAPath()
libraryjars fileTree("$ideaPath/plugins/java/lib").filter { !it.name.startsWith("debugger") }.collect()
libraryjars files("$ideaPath/lib")
libraryjars files(configurations.compile.collect())
def original = jar.archiveFile.get().asFile
def obfuscated = new File(original.parent, "obfuscated.jar")
injars original
outjars file(obfuscated.path)
}
prepareSandbox.dependsOn(myProguardTask)
prepareSandbox.doFirst {
def original = jar.archiveFile.get().asFile
def obfuscated = new File(original.parent, "obfuscated.jar")
if (original.exists() && obfuscated.exists()) {
original.delete()
obfuscated.renameTo(original)
} else {
println "error: some file does not exist, plugin file not obfuscated"
}
}
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 <init>(***);
}
# 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&F. Keep all extensions of javax.swing.plaf.ComponentUI,
# along with the special 'createUI' 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 <fields>;
!private <fields>;
!private <methods>;
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论