`
雨过天晴0521
  • 浏览: 154727 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

如何在ant中调用javascript

 
阅读更多
在java6中内置了一个javascript的engine:

Rhino is an open-source implementation of JavaScript written entirely in Java. It is typically embedded into Java applications to provide scripting to end users. It is embedded in J2SE 6 as the default Java scripting engine.

应用场景1.

在工作中, 我遇到了这样一个应用场景. 调用ant时传的属性参数中有连接数据库的密码, 在log中会显示出来, 如果将密码加密, 那么又会报数据库端的验证错误, 说不认这个经过加密的密码. 怎么办, 有两种方法, 一个是用java写自定义的ant task来解密传给ant script的密码. 然后用明文密码来连接数据库. 写java的缺点在于每次都要事先编译好这个ant task. 还有一种方法是在ant script写一个javascript task. 当然javascript可以调用java的解密函数, 这样不用每次运行ant script前都编译task. 具体脚本如下:

<project name="sfamx.cleanupdb" default="cleanup.db.logging">

    <dirname property="sfamx.ddl.dir" file="${ant.file.sfamx.ddl.build}"/>

    <target name="cleanupall" depends="replace.db.password, cleanup.db.logging"/>

    <path id="jdbc.classpath">
        <fileset dir="${db.driver.path}" includes="*.jar"/>
    </path>
    
    <property name="plaintext.password" value="${plainText}"/>

    <target name="replace.db.password">
    <script language="javascript">
    <classpath>
            <!-- for xxx 3.2 -->
            <pathelement location="${tibco.home}/components/shared/1.0.0/plugins/com.tibco.security.tibcrypt_2.15.0.009.jar"/>
            <pathelement location="${tibco.home}/components/shared/1.0.0/plugins/com.tibco.tpcl.org.slf4j.log4j12_1.6.200.001/slf4j-log4j12-1.5.2.jar"/>
            <pathelement location="${tibco.home}/components/shared/1.0.0/plugins/com.tibco.tpcl.org.slf4j.log4j12_1.6.200.001/slf4j-api-1.5.2.jar"/>
            <pathelement location="${tibco.home}/components/shared/1.0.0/plugins/com.tibco.tpcl.org.apache.log4j_1.2.400.002/log4j-1.2.15.jar"/>
            <!-- for xxx 3.1.5 -->
            <pathelement location="${tibco.home}/components/shared/1.0.0/plugins/com.tibco.security.tibcrypt_2.14.300.006.jar"/>
            <pathelement location="${tibco.home}/components/shared/1.0.0/plugins/com.tibco.tpcl.org.slf4j.log4j12_1.5.101.001/slf4j-log4j12-1.5.2.jar"/>
            <pathelement location="${tibco.home}/components/shared/1.0.0/plugins/com.tibco.tpcl.org.slf4j.log4j12_1.5.101.001/slf4j-api-1.5.2.jar"/>
            <pathelement location="${tibco.home}/components/shared/1.0.0/plugins/com.tibco.tpcl.org.apache.log4j_1.2.300.004/log4j-1.2.15.jar"/>
    </classpath>
    <![CDATA[
        importPackage(com.tibco.security);
        var encryptedPassword = project.getProperty("admin.db.password");
        var decryptedPassword = ObfuscationEngine.decrypt(encryptedPassword);
        var plainText = new java.lang.String(decryptedPassword);
        project.setProperty("plaintext.password", plainText)
    ]]>
    </script>
    </target>

    <target name="cleanup.db.logging" depends="replace.db.password" 
            description="Run ddl to cleanup commonlogging tables in external database for amx administrator">
       <sql
            driver="${admin.db.driver}"
            url="${admin.db.url}"
            userid="${admin.db.username}"
            password="${plaintext.password}"
            print="yes">
           <classpath refid="jdbc.classpath"/>
           <transaction  src="./${db.ddl.path}/drop_commonlogging.ddl"/>
       </sql>
    </target>
</project>


输出

05/25/12 18:46:55.406 INFO: [ProcessWrapper] Executing: D:\build\fabric\DSEngine\resources\win32\wrappid.exe,D:\build\fabric\DSEngine\work\yangxiaoming-lt-1\antcall.pid,D:/build/fabric/DSEngine/work/yangxiaoming-lt-1/tibcoamx/tibcojre/1.6.0/bin/java,-cp,D:/build/fabric/DSEngine/work/yangxiaoming-lt-1/tibcoamx/tools/lib/antpackage.jar,org.apache.tools.ant.launch.Launcher,-f,D:\build\fabric\DSEngine\work\yangxiaoming-lt-1\scripts\cleanupDDL\cleanupDB.xml,-Dadmin.db.password=#!Panbl6s1FhkBUM70G9T+okR+fv5Nwoq+fYUx+SLzZi8=,-Dadmin.db.url=jdbc:sqlserver://192.168.71.99:1433;databasename=amxdb,-Dadmin.db.username=sa,-Ddb.ddl.path=mssql300,-Ddb.driver.path=D:\build\fabric\DSEngine\work\yangxiaoming-lt-1/fabric/mssql2008_driver,-Dtibco.home=D:/build/fabric/DSEngine/work/yangxiaoming-lt-1/tibcoamx,-Dadmin.db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver,cleanup.db.logging,
05/25/12 18:46:55.609 INFO: [ProcessWrapper] [STDOUT] Buildfile: D:\build\fabric\DSEngine\work\yangxiaoming-lt-1\scripts\cleanupDDL\cleanupDB.xml
05/25/12 18:46:55.875 INFO: [ProcessWrapper] [STDOUT]
05/25/12 18:46:55.875 INFO: [ProcessWrapper] [STDOUT] replace.db.password:
05/25/12 18:46:55.984 INFO: [ProcessWrapper] [STDOUT]    [script] log4j:WARN No appenders could be found for logger (com.tibco.security.TIBCOSecurity).
05/25/12 18:46:55.984 INFO: [ProcessWrapper] [STDOUT]    [script] log4j:WARN Please initialize the log4j system properly.
05/25/12 18:46:56.500 INFO: [ProcessWrapper] [STDOUT]      [echo] Tibc02008
05/25/12 18:46:56.500 INFO: [ProcessWrapper] [STDOUT]
05/25/12 18:46:56.500 INFO: [ProcessWrapper] [STDOUT] cleanup.db.logging:
05/25/12 18:46:56.687 INFO: [ProcessWrapper] [STDOUT]       [sql] Executing resource: D:\build\fabric\DSEngine\work\yangxiaoming-lt-1\scripts\cleanupDDL\mssql300\drop_commonlogging.ddl
05/25/12 18:46:56.687 INFO: [ProcessWrapper] [STDOUT]       [sql] 0 rows affected
05/25/12 18:46:56.687 INFO: [ProcessWrapper] [STDOUT]       [sql] 1 of 1 SQL statements executed successfully
05/25/12 18:46:56.703 INFO: [ProcessWrapper] [STDOUT]
05/25/12 18:46:56.703 INFO: [ProcessWrapper] [STDOUT] BUILD SUCCESSFUL
05/25/12 18:46:56.703 INFO: [ProcessWrapper] [STDOUT] Total time: 1 second


在ant中使用javascript, 在javascript又调用了java, 所以一定要注意数据的boxing和unboxing. 比如用java的方法返回decryptedPassword 时, 它其实已经被unboxing了, 失去了java的char[]类型, 但内在传递的值是不变的, 所以我们需要对它重新boxing, 让它成为java的String类型, 在boxing他的char[]值同时解码, 获得实际字符串, 也就是明文. 再将它传递给javascript的变量.

换句话说, 有的情况js和java的函数相同, 如果var的类型不明显,javascript引擎不知该调用哪个方法, 建议用var input = new String(strInput)

应用场景2.

在工作当中我遇到了这样一种情况, 安装时需要选择administration, runime host这样的安装profile, 这两者是交集. 我们的目的是想以administration里的所有assembly names作为exclude的对象, 在安装runtime host时加以过滤. 从而保留runtime host独有的assemblies.

<target name="gen-zip-excludes">
   <path id="my.path">
     <dirset dir="${installation.root}/components/shared/1.0.0/features" includes="*">
                <depth max="1"/>
     </dirset>
     <dirset dir="${installation.root}/components/shared/1.0.0/plugins" includes="*">
                <depth max="1"/>
     </dirset>
     <fileset dir="${installation.root}/components/shared/1.0.0/plugins" includes="*.jar"/>
   </path>
    <pathconvert targetos="unix" property="zip.excludes" refid="my.path" pathsep="${file.separator}**,">
    </pathconvert>
</target>
...
...
   <scriptdef name="bwsefilter" language="javascript">
     <attribute name="text" />
     <attribute name="pluginspath" />
     <attribute name="featurespath" />
     <attribute name="property" />
     <![CDATA[
       var text = new java.lang.String(attributes.get("text"));
       var path1 = new java.lang.String(attributes.get("pluginspath"));
       var path2 = new java.lang.String(attributes.get("featurespath"));
       var replaced = text.replaceAll(path1,"**").replaceAll(path2, "**");
       project.setProperty(attributes.get("property"), replaced);
     ]]>
  </scriptdef>

  <target name="bwse.distribution.filter">
     <bwsefilter text="${zip.excludes}" pluginspath="${installation.root}/components/shared/1.0.0/features" featurespath="${installation.root}/components/shared/1.0.0/plugins" property="file.excludes"/>
  </target>
...
...
  <target name="bwse.distribution.package" depends="bwse.distribution.clean">
       <zip destfile="${bwse.distribution.name}">
           <zipfileset dir="${installation.root}/" includes="bwse/"/>
           <zipfileset dir="${installation.root}/components" prefix="components" excludes="${file.excludes}"/>
           <zipfileset dir="${temp.dir}/" includes="grid-library.xml"/>
           <zipfileset dir="${temp.dir}/" includes="*.properties"/>
           <zipfileset dir="${download.root}/${bwse.installer.name}" includes="TIB_bwse_${bwse.installer.version}_license.pdf"/>
       </zip>
     <delete includeemptydirs="true">
          <fileset dir="${temp.dir}/"/>
      </delete>
  </target>


注意以下问题

1.在这段脚本中:
    <pathconvert targetos="unix" property="zip.excludes" refid="my.path" pathsep="${file.separator}**,">


初看可能会疑惑, targetos为什么标称unix呢? 其实是想和后面的pluginspath="${installation.root}/components/shared/1.0.0/features" featurespath="${installation.root}/components/shared/1.0.0/plugins" 兼容, 如果是没有targetos, 默认的情况下就会根据所在的平台自己判断, 如果在windows上, ${file.separator}就会成为'\', 这样与后面的没办法匹配, 也就过滤失败. 其实ant或者直接说java里都用'/'作为文件分隔符, 即使pluginspath和featurespath里用的是'\'也一样会失败的.

还有人可能会有疑问, pathsep的分隔符为什么要用'${file.separator}**,',而不是',' 原因是我们收集的文件集合里有的是文件夹, 有的是文件, 文件夹必须用'**/文件夹/**过滤', 文件用'**/文件', 而文件用'**/文件/**'也没有问题, 为了把两者都一次性过滤, 所以都用'**/文件或文件夹/**'来过滤.

2. 在<![CDATA[]]>中, 我们可以用javascript和java代码来完成自定义task, 但js和java混用的话,函数又类似的时候可能会混淆编译器. 所以建议要么用javascript, 要么用java的函数, 用java之前最好把js的字符串用new java.lang.String();转化一下, 比如var text = new java.lang.String(attributes.get("text"));


具体可以参考下这篇文章:
https://developer.mozilla.org/zh_tw/Core_JavaScript_1.5_%E6%95%99%E5%AD%B8/LiveConnect_%E6%A6%82%E8%A6%81/%E8%B3%87%E6%96%99%E9%A1%9E%E5%9E%8B%E7%9A%84%E8%BD%89%E6%8F%9B/%E5%BE%9E_JavaScript_%E5%88%B0_Java_%E7%9A%84%E8%BD%89%E6%8F%9B


补充:

To do more interesting things with Ant, you have access to properties, targets, and references. For an explanation of properties, targets, and references, refer to the ant manual

project.getProperty(string propertyName);
project.getUserProperty(string propertyName);
project.getTarget(string targetId);
project.getReference(string refereceId);

project is a shortcut for getProject(), which returns the project object.
self returns the script task itself for logging and other task specific utilities.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics