Skip to main content
 首页 » 编程设计

ant中JavaFx TableView 内容在混淆后消失

2024年09月07日5lonelyxmas

我创建了一个 JavaFX 应用程序,它有许多 TableView 来显示内容,如果我运行 Jar 文件,应用程序可以正常工作。由于我需要将应用程序分发给我的客户,因此我的代码应该被混淆。我正在使用 Proguard-4.8 来混淆我的代码。

我使用 Ant 创建了一个示例 TableView 构建脚本来混淆示例 jar。

混淆之前仅兼容 jar -

Before Obfuscation

混淆 Jar 后 -

After Obfuscation

我已将完整的构建脚本项目上传至 - http://neelamsharma.s3.amazonaws.com/SampleObfuscationBuildScript.zip

我已经完全运行了它。你会发现-

  1. build.xml - http://neelamsharma.s3.amazonaws.com/SampleObfuscationBuildScript/build.xml
  2. 未混淆的编译 Jar - http://neelamsharma.s3.amazonaws.com/SampleObfuscationBuildScript/Sample.jar
  3. 混淆的 Jar - http://neelamsharma.s3.amazonaws.com/SampleObfuscationBuildScript/obfuscated/SampleObfuscated.jar
  4. Proguard.map - http://neelamsharma.s3.amazonaws.com/SampleObfuscationBuildScript/obfuscated/ObfuscatedProguard.map
  5. 源 Java 类 - http://neelamsharma.s3.amazonaws.com/SampleObfuscationBuildScript/src/TableViewWithButton.java

其他事情是 - 这是我的 build.xml 文件 -

<project name="sample" default="cleanBuildPackage" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant"> 
    <property environment="env"/> 
 
 
    <property name="WorkingFolder" location="."/> 
    <property name="ClassPath" location="${env.JAVA_HOME}/jre/lib/jfxrt.jar;${env.JAVA_HOME}/lib/ant-javafx.jar;${WorkingFolder}/lib/proguard.jar;"/> 
    <property name="dist" value="dist"/>   
    <property name="main.class" value="TableViewWithButton"/> 
    <property name="app.name" value="Sample"/> 
 
 
    <target name="init"> 
        <echo message="Java installation directory: ${java.home}"/> 
        <!-- Create the time stamp --> 
        <tstamp/> 
 
        <delete dir="${WorkingFolder}/build"/> 
        <delete dir="${dist}"/> 
        <mkdir dir="${dist}"/> 
        <mkdir dir="${WorkingFolder}/build"/> 
    </target> 
 
    <target name="CompilingSample" depends="init"> 
        <taskdef resource="com/sun/javafx/tools/ant/antlib.xml"       
             uri="javafx:com.sun.javafx.tools.ant" classpath=".;${env.JAVA_HOME}/jre/lib/jfxrt.jar"/> 
        <javac classpath="${ClassPath};" srcdir="${WorkingFolder}/src" destdir="${WorkingFolder}/build"/> 
    </target>  
 
 
 
    <target name="CreatingSampleJar" depends="CompilingSample" description="generate the distribution" > 
        <taskdef resource="com/sun/javafx/tools/ant/antlib.xml"       
        uri="javafx:com.sun.javafx.tools.ant" classpath="${env.JAVA_HOME}/lib/ant-javafx.jar"/> 
            <fx:jar destfile="${WorkingFolder}/${app.name}.jar"> 
                    <fx:application mainClass="${main.class}"/> 
                <fileset dir="${WorkingFolder}/build"/> 
            </fx:jar> 
    </target>  
 
    <target name="Ofuscating" depends="CreatingSampleJar" > 
 
        <taskdef resource="proguard/ant/task.properties" classpath="${WorkingFolder}/lib/proguard.jar" /> 
            <mkdir dir="obfuscated"/> 
                <proguard printmapping="obfuscated/ObfuscatedProguard.map" 
                                renamesourcefileattribute="SourceFile" ignorewarnings="true"> 
 
                    -dontshrink 
                    -dontoptimize 
 
                    -libraryjars "${java.home}/lib/rt.jar" 
                    -libraryjars "${java.home}/lib/javaws.jar" 
                    -libraryjars "${env.JAVA_HOME}/lib/ant-javafx.jar" 
                    -libraryjars "${env.JAVA_HOME}/jre/lib/jfxrt.jar"            
 
 
                    -injars ${WorkingFolder}/${app.name}.jar                                     
 
                    -outjars ${WorkingFolder}/Obfuscated.jar 
 
                    -ignorewarnings 
 
                    <keepattribute name="InnerClasses" /> 
                        <keepattribute name="SourceFile" /> 
                        <keepattribute name="LineNumberTable" /> 
                        <keepattribute name="Deprecated" /> 
                        <keepattribute name="*Annotation*" /> 
                        <keepattribute name="Signature" /> 
 
                    -adaptresourcefilecontents **.fxml,**.properties,META-INF/MANIFEST.MF,images/*,publicCerts.store,.version 
 
                            <!--   
                            If I am adding this then I am able to see TableView Contents, but it do not obfuscate all public classes and their methods. 
                            <keep access="public"> 
                                                 <method access="public protected" /> 
                                        </keep>  
                                         --> 
 
                    -keepclassmembernames class * { 
                        @javafx.fxml.FXML *; 
                    }  
                    -keepclasseswithmembers public class com.javafx.main.Main, TableViewWithButton { 
                            public static void main(java.lang.String[]); 
                    }                     
            </proguard> 
 
 
    </target> 
 
    <target name="Movejar" depends="Ofuscating"> 
        <move 
        file="${WorkingFolder}/Obfuscated.jar" 
        tofile="obfuscated/${app.name}Obfuscated.jar" verbose="true" overwrite="true" /> 
    </target> 
 
 
 
    <target name="cleanBuildPackage" depends="Movejar"> 
            <fx:deploy width="800" height="600" nativeBundles="all" outdir="${dist}" outfile="${app.name}"> 
                <fx:info title="${app.name}"/> 
                    <fx:application name="${app.name}" mainClass="${main.class}"/> 
                    <fx:resources> 
                        <fx:fileset dir="${dist}" includes="*.jar"/> 
             </fx:resources> 
         </fx:deploy> 
    </target> 
 
</project> 

在 build.xml 中,如果我添加此行,那么我可以看到 TableView 内容,但它不会混淆所有公共(public)类及其方法。

<keep access="public"> 
     <method access="public protected" /> 
</keep>  

我需要完全混淆我的项目。是否有其他方法可以混淆 jar 文件而不保持公共(public)类未混淆,以便我能够完全看到 TableView 文本。

谢谢

尼拉姆·夏尔马

请您参考如下方法:

我建议尝试使用PropertyValueFactory的长形式:

col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Test, String>, 
             ObservableValue<String>>() { 
     public ObservableValue<String> call(TableColumn.CellDataFeatures<Test, String> t) { 
         // t.getValue() returns the Test instance for a particular TableView row 
         return t.getValue().testProperty(); 
         // or 
         return new SimpleStringProperty(t.getValue().getMessage()); 
     } 
  });