NetBeans Forums

 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister   ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
  

A solution: How to obfuscate then sign a JNLP build.

 
Post new topic   Reply to topic    NetBeans Forums -> NetBeans Platform Users
View previous topic :: View next topic  
Author Message
paul260



Joined: 10 Sep 2009
Posts: 14

PostPosted: Mon Mar 28, 2011 2:51 am    Post subject: A solution: How to obfuscate then sign a JNLP build. Reply with quote

Hi All,

I'm posting a JNLP build script which includes jar file obfuscation with Progaurd prior to signing, as I haven't come across this on the forums before, and it took a few days for me to work out. Hopefully this will help out any other ant script newbs such as myself!

I had to modify a copy of jnlp.xml from the sources under nbbuild > netbeans > harness which I kept at the root level of my project, and make a reference to my new jnlp-obfuscate.xml within build.xml, by inserting a cut and paste tweak from suite.xml (also under nbbuild > netbeans > harness).

Here's my mod to build.xml:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
<!-- for some information on what you could do (e.g. targets to override). -->
<!-- If you delete this file and reopen the project it will be recreated. -->
<project name="RCPapp" basedir=".">
    <description>Builds the module suite RCPapp.</description>
    <import file="nbproject/build-impl.xml"/>
    <taskdef resource="proguard/ant/task.properties" classpath="proguard.jar" />

    <target name="run-jnlp-obfuscate" depends="build,-jdk-init" description="Runs this suite as a JNLP application.">
        <ant antfile="jnlp-obfuscate.xml" target="run">
            <reference refid="cluster.path.id"/>
            <property name="jnlp.generate.versions" value="false"/>  <!-- versioning is not enabled w/o app server-->
        </ant>
    </target>
   
</project>


And here's the tweak to the build-jnlp-nowar target in the jnlp.xml (which all happens above <antcall target="copy-branding"/>, giving me my jnlp-obfuscate.xml. Referring to the original jnlp.xml, you'll notice that I've removed jar signing from the subant task, then included a section to obfuscate the jars in the app directory with a Proguard settings.pro file (again at the root level of the project), then lastly included a signjar task with a fileset referring to the now obfuscated jars in the app directory.

Code:
    <target name="build-jnlp-nowar" depends="jnlp-init,jnlp-generate-keystore,jnlp-generate-platform">
        <echo message="Starting build-jnlp-nowar"/>
        <mkdir dir="${jnlp.dest.dir}/app"/>
        <subant target="jnlp" buildpath="${modules.sorted}" inheritrefs="false" inheritall="false">
            <property name="jnlp.dest.dir" value="${jnlp.dest.dir}/app"/>
            <property name="jnlp.master.dir" value="${jnlp.master.dir}"/>
            <property name="jnlp.master.codebase" value="app/"/>
            <property name="jnlp.codebase" value="${jnlp.codebase.app}"/>
            <property name="jnlp.permissions" value="${jnlp.permissions}"/>
        </subant>

        <echo message="Starting obfuscation"/>
        <proguard configuration="settings.pro"/>
        <copy toDir="${jnlp.dest.dir}/app">
            <fileset dir="${jnlp.dest.dir}/processed_jars"/>
        </copy>
        <delete dir="${jnlp.dest.dir}/processed_jars"/>

        <echo message="Signing app jars"/>
        <signjar alias="${jnlp.signjar.alias}"
            keystore="${jnlp.signjar.keystore}"
            storepass="${jnlp.signjar.password}">
            <path>
                <fileset dir="${jnlp.dest.dir}/app" includes="**/*.jar" />
            </path>
        </signjar>

        <antcall target="copy-branding"/>
       
        <signjar
            alias="${jnlp.signjar.alias}"
            keystore="${jnlp.signjar.keystore}"
            storepass="${jnlp.signjar.password}"
            jar="${harness.dir}/jnlp/jnlp-launcher.jar"
            signedjar="${jnlp.dest.dir}/startup.jar"
        />
       
        <pathconvert pathsep="${line.separator}" property="jnlp.branding.jars">
            <path>
                <fileset dir="${jnlp.dest.dir}/branding">
                    <include name="*_${branding.token}.jar"/>
                </fileset>
            </path>
            <mapper type="regexp" from="^.*[/\\]([^/\\]+\.jar)" to='    &lt;jar href="branding/\1"/&gt;'/>
        </pathconvert>
       
        <echo file="${jnlp.master.dir}/resources.xml"><![CDATA[
    <java version="1.6+"/>
    <jar href="startup.jar"/>
    <property name="netbeans.user" value="$${user.home}/.nbapp-${app.name}"/>
]]></echo>
        <concat append="true" destfile="${jnlp.master.dir}/resources.xml">
            <fileset dir="${jnlp.master.dir}">
                <include name="*.ref"/>
            </fileset>
        </concat>
       
        <loadfile property="jnlp.resources" srcfile="${jnlp.master.dir}/resources.xml"/>

        <condition property="netbeans.jnlp.fixPolicy">
            <isfalse value="${jnlp.sign.jars}"/>
        </condition>
        <!-- Anyone knows a better way to negate a property value? -->
        <condition property="netbeans.jnlp.fixPolicy" value="false">
            <istrue value="${jnlp.sign.jars}"/>
        </condition>
       
        <condition property="app.icon.safe" value="${app.icon}" else=".png">
            <isset property="app.icon" />
        </condition>
        <pathconvert property="app.icon.ext">
            <path path="${app.icon.safe}"/>
            <mapper type="regexp" from="^(.*)\.(.*)$$" to="\2"/>
        </pathconvert>
       
        <copy file="${app.icon}" tofile="${jnlp.dest.dir}/master.${app.icon.ext}" failonerror="false"/>
        <copy file="master.jnlp" tofile="${jnlp.dest.dir}/master.jnlp">
            <filterchain>
                <replacestring from="&lt;!--$${jnlp.resources}--&gt;" to="${jnlp.resources}"/>
                <replacestring from="$${jnlp.resources}" to="${jnlp.resources}"/>
                <replacestring from="$${app.name}" to="${app.name}"/>
                <replacestring from="$${app.title}" to="${app.title}"/>
                <replacestring from="$${app.icon}" to="master.${app.icon.ext}"/>
                <replacestring from="$${branding.token}" to="${branding.token}"/>
                <replacestring from="$${netbeans.jnlp.fixPolicy}" to="${netbeans.jnlp.fixPolicy}"/>
            </filterchain>
        </copy>
        <echo>Your JNLP file is generated at ${jnlp.dest.dir}/master.jnlp</echo>
        <!-- The following line will not fail if the branding.jnlp
             is not present, e.g. when the main file was generated using
             harness from 5.x days. -->
        <copy file="branding.jnlp" tofile="${jnlp.dest.dir}/branding.jnlp" failonerror="false">
            <filterchain>
                <replacestring from="$${jnlp.branding.jars}" to="${jnlp.branding.jars}"/>
                <replacestring from="$${app.name}" to="${app.name}"/>
                <replacestring from="$${app.title}" to="${app.title}"/>
                <replacestring from="$${app.icon}" to="master.${app.icon.ext}"/>
                <replacestring from="$${jnlp.permissions}" to="${jnlp.permissions}"/>
            </filterchain>
        </copy>

        <taskdef name="verifyjnlp" classname="org.netbeans.nbbuild.VerifyJNLP" classpath="${harness.dir}/tasks.jar"/>
        <verifyjnlp>
            <fileset file="${jnlp.dest.dir}/master.jnlp"/>
        </verifyjnlp>
    </target>


Lastly, here are my in/out/library jar settings in the settings.pro file:

Code:
-injars       build/jnlp/app/(**/org-*.jar;)

-outjars      build/jnlp/processed_jars

-libraryjars  /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/../Classes/classes.jar:
build/jnlp/app/(**/ext-*.jar;):
build/jnlp/netbeans/(**/*.jar;)


Hope this saves someone else a lot of trouble in obfuscating their Java Web Start RCP app!

Cheers,

Paul.
Back to top
paul260



Joined: 10 Sep 2009
Posts: 14

PostPosted: Thu Mar 31, 2011 7:04 am    Post subject: Reply with quote

Should have mentioned this worked for NetBeans 7.0 Beta 2.

And obviously, change the reference to the jdk classes.jar in the settings.pro file under -libraryjars appropriate to your system (I'm on a Mac).

Cheers.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    NetBeans Forums -> NetBeans Platform Users All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB
By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo