( ! ) Deprecated: Function WP_Dependencies-&gt;add_data() was called with an argument that is <strong>deprecated</strong> since version 6.9.0! IE conditional comments are ignored by all supported browsers. in /var/www/html/wp-includes/functions.php on line 6131
Call Stack
#TimeMemoryFunctionLocation
10.0000484224{main}( ).../index.php:0
20.0000484576require( '/var/www/html/wp-blog-header.php ).../index.php:17
30.08894287760require_once( '/var/www/html/wp-includes/template-loader.php ).../wp-blog-header.php:19
40.09004317080include( '/var/www/html/wp-content/themes/twentyfifteen/archive.php ).../template-loader.php:125
50.09004317080get_header( $name = ???, $args = ??? ).../archive.php:19
60.09004317296locate_template( $template_names = [0 => 'header.php'], $load = TRUE, $load_once = TRUE, $args = [] ).../general-template.php:48
70.09004317392load_template( $_template_file = '/var/www/html/wp-content/themes/twentyfifteen/header.php', $load_once = TRUE, $args = [] ).../template.php:749
80.09004317936require_once( '/var/www/html/wp-content/themes/twentyfifteen/header.php ).../template.php:814
90.09014325344wp_head( ).../header.php:18
100.09014325344do_action( $hook_name = 'wp_head' ).../general-template.php:3197
110.09014325560WP_Hook->do_action( $args = [0 => ''] ).../plugin.php:522
120.09014325560WP_Hook->apply_filters( $value = '', $args = [0 => ''] ).../class-wp-hook.php:365
130.09034447328wp_enqueue_scripts( '' ).../class-wp-hook.php:341
140.09034447328do_action( $hook_name = 'wp_enqueue_scripts' ).../script-loader.php:2311
150.09034447544WP_Hook->do_action( $args = [0 => ''] ).../plugin.php:522
160.09034447544WP_Hook->apply_filters( $value = '', $args = [0 => ''] ).../class-wp-hook.php:365
170.09054449432twentyfifteen_scripts( '' ).../class-wp-hook.php:341
180.09064450952wp_style_add_data( $handle = 'twentyfifteen-ie', $key = 'conditional', $value = 'lt IE 9' ).../functions.php:440
190.09064450952WP_Styles->add_data( $handle = 'twentyfifteen-ie', $key = 'conditional', $value = 'lt IE 9' ).../functions.wp-styles.php:245
200.09064450952WP_Dependencies->add_data( $handle = 'twentyfifteen-ie', $key = 'conditional', $value = 'lt IE 9' ).../class-wp-styles.php:385
210.09064450952_deprecated_argument( $function_name = 'WP_Dependencies->add_data()', $version = '6.9.0', $message = 'IE conditional comments are ignored by all supported browsers.' ).../class-wp-dependencies.php:317
220.09064451272wp_trigger_error( $function_name = '', $message = 'Function WP_Dependencies->add_data() was called with an argument that is <strong>deprecated</strong> since version 6.9.0! IE conditional comments are ignored by all supported browsers.', $error_level = 16384 ).../functions.php:5925
230.09074452024trigger_error( $message = 'Function WP_Dependencies-&gt;add_data() was called with an argument that is <strong>deprecated</strong> since version 6.9.0! IE conditional comments are ignored by all supported browsers.', $error_level = 16384 ).../functions.php:6131

( ! ) Deprecated: Function WP_Dependencies-&gt;add_data() was called with an argument that is <strong>deprecated</strong> since version 6.9.0! IE conditional comments are ignored by all supported browsers. in /var/www/html/wp-includes/functions.php on line 6131
Call Stack
#TimeMemoryFunctionLocation
10.0000484224{main}( ).../index.php:0
20.0000484576require( '/var/www/html/wp-blog-header.php ).../index.php:17
30.08894287760require_once( '/var/www/html/wp-includes/template-loader.php ).../wp-blog-header.php:19
40.09004317080include( '/var/www/html/wp-content/themes/twentyfifteen/archive.php ).../template-loader.php:125
50.09004317080get_header( $name = ???, $args = ??? ).../archive.php:19
60.09004317296locate_template( $template_names = [0 => 'header.php'], $load = TRUE, $load_once = TRUE, $args = [] ).../general-template.php:48
70.09004317392load_template( $_template_file = '/var/www/html/wp-content/themes/twentyfifteen/header.php', $load_once = TRUE, $args = [] ).../template.php:749
80.09004317936require_once( '/var/www/html/wp-content/themes/twentyfifteen/header.php ).../template.php:814
90.09014325344wp_head( ).../header.php:18
100.09014325344do_action( $hook_name = 'wp_head' ).../general-template.php:3197
110.09014325560WP_Hook->do_action( $args = [0 => ''] ).../plugin.php:522
120.09014325560WP_Hook->apply_filters( $value = '', $args = [0 => ''] ).../class-wp-hook.php:365
130.09034447328wp_enqueue_scripts( '' ).../class-wp-hook.php:341
140.09034447328do_action( $hook_name = 'wp_enqueue_scripts' ).../script-loader.php:2311
150.09034447544WP_Hook->do_action( $args = [0 => ''] ).../plugin.php:522
160.09034447544WP_Hook->apply_filters( $value = '', $args = [0 => ''] ).../class-wp-hook.php:365
170.09054449432twentyfifteen_scripts( '' ).../class-wp-hook.php:341
180.12014453128wp_style_add_data( $handle = 'twentyfifteen-ie7', $key = 'conditional', $value = 'lt IE 8' ).../functions.php:444
190.12014453128WP_Styles->add_data( $handle = 'twentyfifteen-ie7', $key = 'conditional', $value = 'lt IE 8' ).../functions.wp-styles.php:245
200.12014453128WP_Dependencies->add_data( $handle = 'twentyfifteen-ie7', $key = 'conditional', $value = 'lt IE 8' ).../class-wp-styles.php:385
210.12014453128_deprecated_argument( $function_name = 'WP_Dependencies->add_data()', $version = '6.9.0', $message = 'IE conditional comments are ignored by all supported browsers.' ).../class-wp-dependencies.php:317
220.12014453448wp_trigger_error( $function_name = '', $message = 'Function WP_Dependencies->add_data() was called with an argument that is <strong>deprecated</strong> since version 6.9.0! IE conditional comments are ignored by all supported browsers.', $error_level = 16384 ).../functions.php:5925
230.12024453672trigger_error( $message = 'Function WP_Dependencies-&gt;add_data() was called with an argument that is <strong>deprecated</strong> since version 6.9.0! IE conditional comments are ignored by all supported browsers.', $error_level = 16384 ).../functions.php:6131

yGuard – Java™ Bytecode Obfuscator and Shrinker

yGuard is a free Java bytecode obfuscator and shrinker that improves your software deployment by prohibiting unwanted access to your source code and drastically shrinking the processed Jar files at the same time.


Features




  • yGuard is absolutely free! Contrary to expensive commercial products of our competitors providing the same amount of features as yGuard or less, yGuard is free.

  • yGuard is an Ant task! Existing tools use proprietary mechanisms to invoke or configure the task of obfuscation. As an Ant task, yGuard can be seamlessly integrated into your deployment process using XML syntax.

  • yGuard provides highly configurable name obfuscation that will protect your intellectual property from reverse engineering.

  • yGuard provides elaborate code shrinking functionality through dependency analysis.

  • yGuard 2.0 offers a new powerful and easy to use XML syntax that allows the effortless definition of code entities e.g. based on pattern sets or inheritance.

  • yGuard will correctly obfuscate and shrink programs that depend on external libraries.

  • yGuard can automatically rename and adjust textual resource files according to the obfuscation scheme.

  • yGuard can scramble and unscramble or shrink line number table information. This means that debugging an obfuscated program is still achievable without weakening the obfuscation.

  • yGuard can create patches! During each obfuscation run, yGuard produces XML output that can be used to create subsequent patches of already deployed obfuscated applications.

  • yGuard supports JDK 1.5 features and correctly obfuscates classes compiled with its new features.

Why Use yGuard?



  • Name Obfuscation: protects your .class files from reverse engineering by replacing package, class, method, and field names with inexpressive characters. If afterwards the obfuscated .class files are decomplied, it will be extremely diffcult to derive the original purpose of the obfuscated code entities.
    As an additional side-effect, name obfuscation will significantly reduce the size of your application, depending on the chosen mapping scheme.

  • Code Shrinking: drastically reduces the size of the input Jar files if your application does not use all of the contained bytecode.
    The shrinking engine analyzes the bytecode of all input Jar files in order to determine which code entities can not be reached from a set of given code entry points. These obsolete code fragments (either entire classes or single methods and fields) will then be removed by yGuard. If you use any third party libraries, you will probably benefit a lot from the yGuard shrinking engine, since applications usually do not use all of the functionality provided by an external library and a large fraction of the contained bytecode and resources can be safely removed.

YGuard build Sample

<?xml version=”1.0″ encoding=”UTF-8″?>
  <project name=”ESI” default=”yguard” basedir=”.”>
    <!– edit the following lines to your needs –>
    <target name=”init”>
      <property name=”project_name” value=”ESI”/>
      <property name=”srcDir” value=”src/main”/>
      <property name=”classDir” value=”classes”/>
      <property name=”jar” value=”${project_name}.jar”/>
      <property name=”obfjar” value=”${project_name}_obf.jar”/>
      <property name=”renamelog” value=”${project_name}_renamelog.xml”/>
      <property name=”shrinklog” value=”${project_name}_shrinklog.xml”/>    
      <mkdir dir=”${classDir}” />
      <property name=”lib” value=”E:/Projects/ESI/lib” />
      <path id=”myclasspath”>
     <fileset dir=”${lib}”>
       <include name=”*.jar”/>
     </fileset>
   </path>
    </target>

    <target depends=”jar” name=”yguard”>
      <taskdef name=”yguard” classname=”com.yworks.yguard.YGuardTask” classpath=”D:\yguard-2.2.0\lib\yguard.jar”/>
      <!– the following can be adjusted to your needs –>
      <yguard>
        <inoutpair in=”${jar}” out=”${obfjar}”/>
        <shrink logfile=”${shrinklog}”/>
        <rename logfile=”${renamelog}”>        
          <keep>
           <package>
             <patternset>
               <include name=”org.apache.*”/>
             </patternset>
           </package>
          </keep>
        </rename>
      </yguard>
    </target>
    <!– compile –>
    <target name=”compile” depends=”init”>
      <javac classpathref=”myclasspath” srcdir=”${srcDir}” destdir=”${classDir}”/>
    </target>
    <!– create .jar –>
    <target name=”jar” depends=”compile”>
      <jar jarfile=”${jar}” basedir=”${classDir}” includes=”**”>
        <fileset dir=”E:/Projects/ESI/resource/conf”>
          <include name=”*.xml”/>
        </fileset>
      </jar>
    </target>
    <!– removes all that has been built –>
    <target name=”clean” depends=”init”>
      <delete dir=”${classDir}” includeEmptyDirs=”true” />
    </target>
  </project>
  <!– end file build.xml –>

Name Obfuscation Using yGuard





Name Obfuscation Using yGuard



yGuard is a Java byte code obfuscator that can be used for effective name obfuscation of Java byte code. It is bundled with every yFiles distribution (see the yGuard README file), and is also freely available.


Since yGuard fulfills the obfuscation requirements of the yFiles license terms, it is a perfectly suited tool to protect the yFiles part of any yFiles-based application. (Of course, it is also the perfect tool to protect the entire application.)


yGuard is available as an Apache Ant task for easy integration into any Ant-based build process. Example A.2, “Using the yGuard Ant task” shows an Ant build file’s target that obfuscates the yFiles part of an application.



Note


The example uses yGuard 2.0 syntax.



Example A.2. Using the yGuard Ant task


<!– Obfuscates the yFiles part of an application (i.e., y.jar) and adjusts –>
<!– the non-yFiles part given by the application’s Jar file accordingly. –>
<target name=”obfuscate” depends=”jar”>
  <!– yGuard Ant task. –>
  <taskdef name=”yguard”
           classname=”com.yworks.yguard.YGuardTask”
           classpath=”${yGuardJar}”/>
  <!– Integrated obfuscation and name adjustment… –>
  <yguard>
    <!– Obfuscate the yFiles Jar. –>
    <inoutpair in=”${yJar}” out=”${yJarObf}”/>
    <!– While obfuscating, adjust the names of yFiles features in the –>
    <!– application’s Jar file. –>
    <inoutpair in=”${myAppJar}” out=”${myAppJarObf}”/>
   
    <!– …using the yGuard ‘rename’ task. –>
    <rename logfile=”${obfuscationLog}” replaceClassNameStrings=”true”>
   
      <property name=”obfuscation-prefix” value=”myprefix”/>
      <keep>
        <class classes=”private” methods=”private” fields=”private”>
          <patternset>
            <include name=”com.mycompany.myApp.**”/>
          </patternset>
        </class>
      </keep>
     
      <!– Adjust all occurences of now obfuscated names in plain-text –>
      <!– files, too. –>
      <!– For example, the names of property resource bundle files for –>
      <!– yFiles classes must be adjusted to reflect the yFiles class’s –>
      <!– obfuscated name. –>
      <adjust replaceName=”true”>
        <include name=”y/**/*.properties”/>
      </adjust>
     
    </rename>
  </yguard>
</target>


For detailed explanations of yGuard’s Ant syntax, please see the yGuard manual.






Adjusting Names



Any code that makes use of yFiles features, or more specifically uses names of yFiles features, needs to be adjusted to their new names. This adjustment is automatically performed for all Jar files given to the yGuard obfuscation machinery using the <inoutpair> element.


Using yGuard’s <adjust> element (inside the <obfuscate> element), any additional plain-text files that are not processed by the obfuscation itself, e.g., resource files, can be adjusted in several ways, too. For example, a file’s path, its name, and also its content are subject to possible modifications.






Checking Obfuscation Success



During the obfuscation process, yGuard optionally generates a log file that contains all original names, their new obfuscated names, and also additional statistical information in XML-based syntax. The log file is an important document, since it shows the mapping of original to obfuscated names. To display the information nicely, yGuard offers a convenient reverse name look-up feature.


Example A.3, “yGuard’s command line syntax” shows the command line syntax to invoke yGuard’s reverse name look-up. Given a generated log file (or its GZip compressed variant), both the original class, method, and field names and their obfuscated counterparts are conveniently presented in a tree view, as depicted in Figure A.1, “yGuard’s reverse name look-up view”.



Example A.3. yGuard’s command line syntax

java -jar yguard.jar [yGuard_obfuscation_log_file.xml[.gz]]


Figure A.1. yGuard’s reverse name look-up view










yGuard's reverse name look-up view.

To ensure that the yFiles API has been properly obfuscated, all public and protected class, method, and field names must be present in the tree view presented by yGuard’s reverse name look-up feature. In other words, all names of such features must have been replaced by new names that are distinctly different from their originals.






Tutorial Demo Code



For an example on how to obfuscate the yFiles part of a yFiles-based application using yGuard, see the obfuscation demo’s Ant build file (included with the yFiles Complete distribution). The build file also shows how to adjust the occurences of obfuscated names of any yFiles features in properties files.

Generating Undeclared Methods

Eclipse has many features that make the job of a programmer easy. Here a simple project is created and will use few of those features to demonstrate how easy programming can be using Eclipse. Most of the new programmers, ignore these and prefer to code everything themselves which is time consuming.




  1. First creating a package: really simple. Right click the project name and click “ New ” – > “ Package” . Name it as “car” .


  2. Creating a class in it named “ Car ” and defined 2 private attributes namely “ doors ” , “ seats ” . Now generate getters/setters for that. Eclipse can generate those for us. In the Source menu, click “ Generate getters and setters ” .



  3. Now make another class in the same package named “ Honda ”. Create a “ main ” method in this class. Eclipse will generate “ main ” method once you check the “ generate main method ” checkbox while creating the class.

  4. Also to make Car class to be the superclass for “ Honda ” class. Click “ Browse ” button against superclass field of the class declaration window. As “ Car ” class is under package “ cars ”, parent class for Honda will be “ cars.Car ”.


Eclipse will generate the following code:



package cars;public class Honda extends Car {
 
/**
 
* @param args
 
*/

 
public static void main(String[] args) {
 
// TODO Auto-generated method stub
 
}
 
}

In class Honda, following lines of code are added.



	Car car1 = new Honda(); car1.setSeats(4);
 
car1.setDoors(2);
 
System.out.println(car1.calcNum());

“ car1.calcNum() ” shows error as this method is not declared in the class Car. One way is to go back to class Car and declare the method. Simple way is to click the red cross on the left of the problem line and Eclipse will give you the options for automatically generating the required method in the required class. After generating the required method, Write code according to the requirement in the generated method.



Review the code:



package cars;public class Car {private int doors;private int seats;
 
public int getDoors() {
 
return doors;
 
}
 
public void setDoors(int doors) {
 
this.doors = doors;
 
}
 
public int getSeats() {
 
return seats;
 
}
 
public void setSeats(int seats) {
 
this.seats = seats;
 
}
 
public Object calcNum() {
 
return this.getDoors() * this.getSeats();
 
}
 
}
 
package cars;
 
public class Honda extends Car {
 
public static void main(String[] args) {
 
Car car1 = new Honda();
 
car1.setSeats(4);
 
car1.setDoors(2);
 
System.out.println(car1.calcNum());
 
}
 
}

Generating Code Automatically Using Custom code Template In Eclipse

One of the good features of Eclipse is its auto fill property. This can be further enhanced using its code template feature. Creation of code templates is necessary to improve development productivity. Templates add consistency and uniformity to your code. Eclipse has so many ready-to-use templates. And you can create your own code templates according to your requirements. To use these templates just type the starting characters of the template and then press “CTRL+SPACE”. For example in Ecipse IDE type “tr” and then press “CTRL+SPACE”, It will add “try-catch” block to the code.



This article will guide you to create your own code template. Let us take an example to generate a “if-else” template with one “else if” condition.



  1. Go to the Templates ( Window –> Preference –> java–> Editor –> Templates) .

  2. Click “New”. A window similiar to below appears.

  3. 1.JPG


  4. Fill the details as shown above.

  5. Click “OK”.

  6. Now you can use your custom template in the program like any other template by pressing “CTRL+SPACE” as shown in the below given screenshots.

2.JPG


3.JPG


yWorks Ant Explorer Eclipse Plugin

Eclipse Integration



yWorks Ant Explorer is available as a plugin for the popular Java IDE Eclipse. It supports both the visualization and execution of Ant build scripts.


Installation


You can install the plugin by using Eclipse’s integrated Update Manager, which is available via the menu items “Help” – “Software Updates” – “Find and Install.”
A “New Remote Site” with URL “http://www.yworks.com/eclipse/update” has to be created.


Update Manager Update Manager Update Manager Update Manager


Alternatively, the Jar archive containing the Eclipse plugin can be directly downloaded and extracted into the respective directory (normally, %ECLIPSE_HOME% or ${user.home}/.eclipse).


Usage



The views of yWorks Ant Explorer are opened whenever the visualization of an Ant build script is started via its menu item from the “Package Explorer.”


Furthermore, the views are automatically updated whenever they are visible and an Ant build script is opened inside the editor view.




The visualization view comprises two parts; one view holds the graph that displays dependencies between targets, whilst the other view displays the properties. Edges between properties denote that they are being used in other properties.



Further information for each view can be found in our documentation.


Restrictions



  • Build processes are executed inside the same JVM that runs Eclipse.
    This can lead to side effects, for example regarding the class path or open file handles, etc.
    For problematic build scripts, we recommend that you use the yWorks Ant Explorer stand-alone version instead.

  • “Unesthetic” Icons
    Unfortunately, Eclipse Version 3.0.1 cannot render transparent PNGs in the menu bar. Lower-quality GIFs are used to replace them.

Distributing your Application as an executable JAR file

Distributing your Application as an executable JAR file



A JAR (Java ARchive) is a way of packaging together all of the resources associated with a program (class files, images, sounds, etc.). Putting your program in a JAR allows it to be distributed as a single executable file, saving space and simplifying the download process. The information in this tutorial applies to Java version 1.2 or higher. For more information about JAR files, follow Sun’s tutorial. To learn about signing the JAR and Java Web Start.



A simple example. Let’s say we wanted to distribute the simple program Hello.java as a JAR. First, we create a text file named Hello.mf which contains:


Manifest-Version: 1.0
Main-Class: Hello
Then, we create the archive by typing:
jar cmf Hello.mf Hello.jar Hello.class Hello.java
and run it by typing:
java -jar Hello.jar
The file Hello.jar can now be downloaded and executed.


Creating an executable JAR file. Here is the general procedure for creating an executable JAR:




  1. Compile your java code, generating all of the program’s class files.


  2. Create a manifest file containing the following 2 lines:
    Manifest-Version: 1.0
    Main-Class: name of class containing main
    The name of the file should end with the .mf suffix. It is important that the file ends with a blank line.


  3. To create the JAR, type the following command:
    jar cmf manifest-file jar-file input-files
    The input-files must include any class files, images, sounds, etc. that your program uses. Optionally, you can include the program’s .java files in the JAR. See below for adding directories ot the JAR.


  4. To view the contents of the JAR, type:
    jar tf jar-file


  5. Execute the application from the command line by typing:
    java -jar jar-file
    If the application is GUI-based, you can also launch it by double-clicking the JAR file.

Accessing resources in a JAR. In general, the first step in accessing a JAR resource involves creating a URL. This might require modifying your program. For example, you can no longer use the following code fragment to read in an image that is stored in a file as follows


Image image = Toolkit.getDefaultToolkit().getImage(filename);
Instead, create the URL object using
URL url = getClass.getResource(filename);
Image image = Toolkit.getDefaultToolkit().getImage(url);
Or, if the code is in a static method of class X, then create the URL with
URL url = X.class.getResource(filename); 
Now, the resource can be accessed the same way, regardless of whether it is in a JAR or the current directory. See the method play(filename) in StdDraw.java for an example involving audio clips, and and the constructor In(String s) in In.java for an example involving text files.

JAR Subdirectories. The JAR format also support storing files in a directory structure. Consider a program Sample.java, which uses the Turtle Graphics interface to display a collection of pictures stored in a subdirectory called images. Our working directory looks like:





The Manifest should read:


Manifest-Version: 1.0
Main-Class: Sample

To create the JAR, type:


jar cmf Sample.mf Sample.jar Sample.class Turtle.class Sample.java Turtle.java images

The contents listing appears as:


META-INF/
META-INF/MANIFEST.MF
Sample.class
Turtle.class
Sample.java
Turtle.java
images/
images/image1.gif
images/image2.gif
images/image3.gif

Notice that the directory structure is still preserved (the META-INF directory is created to hold the manifest and other general information about the JAR).


Setting Package Version Information

Setting Package Version Information

You may need to include package version information in a JAR file’s manifest. You provide this information with the following headers in the manifest:




























Headers in a manifest
Header Definition
Name The name of the specification.
Specification-Title The title of the specification.
Specification-Version The version of the specification.
Specification-Vendor The vendor of the specification.
Implementation-Title The title of the implementation.
Implementation-Version The build number of the implementation.
Implementation-Vendor The vendor of the implementation.


One set of such headers can be assigned to each package. The versioning headers should appear directly beneath the Name header for the package. This example shows all the versioning headers:


Name: java/util/
Specification-Title: Java Utility Classes
Specification-Version: 1.2
Specification-Vendor: Sun Microsystems, Inc.
Implementation-Title: java.util
Implementation-Version: build57
Implementation-Vendor: Sun Microsystems, Inc.


For more information about package version headers, see the Package Versioning specification .



An Example


We want to include the headers in the example above in the manifest of MyJar.jar.

We first create a text file named Manifest.txt with the following contents:


Name: java/util/
Specification-Title: Java Utility Classes
Specification-Version: 1.2
Specification-Vendor: Sun Microsystems, Inc.
Implementation-Title: java.util
Implementation-Version: build57
Implementation-Vendor: Sun Microsystems, Inc.




Warning : The text file must end with a new line or carriage return. The last line will not be parsed properly if it does not end with a new line or carriage return.


We then create a JAR file named MyJar.jar by entering the following command:
jar cmf MyJar.jar Manifest.txt MyPackage/*.class
This creates the JAR file with a manifest with the following contents:
Manifest-Version: 1.0
Created-By: 1.6.0 (Sun Microsystems Inc.)
Name: java/util/
Specification-Title: Java Utility Classes
Specification-Version: 1.2
Specification-Vendor: Sun Microsystems, Inc.
Implementation-Title: java.util
Implementation-Version: build57
Implementation-Vendor: Sun Microsystems, Inc.

Understanding Signing and Verification

Understanding Signing and Verification

The JavaTM platform enables you to digitally sign JAR files. You digitally sign a file for the same reason you might sign a paper document with pen and ink — to let readers know that you wrote the document, or at least that the document has your approval.

When you sign a letter, for example, everyone who recognizes your signature can confirm that you wrote the letter. Similarly when you digitally sign a file, anyone who “recognizes” your digital signature knows that the file came from you. The process of “recognizing” electronic signatures is called verification.


The ability to sign and verify files is an important part of the Java platform’s security architecture. Security is controlled by the security policy that’s in force at runtime. You can configure the policy to grant security privileges to applets and to applications. For example, you could grant permission to an applet to perform normally forbidden operations such as reading and writing local files or running local executable programs. If you have downloaded some code that’s signed by a trusted entity, you can use that fact as a criterion in deciding which security permissions to assign to the code.


Once you (or your browser) have verified that an applet is from a trusted source, you can have the platform relax security restrictions to let the applet perform operations that would ordinarily be forbidden. A trusted applet can have freedoms as specified by the policy file in force.


The Java platform enables signing and verification by using special numbers called public and private keys. Public keys and private keys come in pairs, and they play complementary roles.


The private key is the electronic “pen” with which you can sign a file. As its name implies, your private key is known only to you so that no one else can “forge” your signature. A file signed with your private key can be verified only by the corresponding public key.


Public and private keys alone, however, aren’t enough to truly verify a signature. Even if you’ve verified that a signed file contains a matching key pair, you still need some way to confirm that the public key actually comes from the signer that it purports to come from.


One more element, therefore, is required to make signing and verification work. That additional element is the certificate that the signer includes in a signed JAR file. A certificate is a digitally signed statement from a recognized certification authority that indicates who owns a particular public key. A certification authority are entities (typically firms specializing in digital security) that are trusted throughout the industry to sign and issue certificates for keys and their owners. In the case of signed JAR files, the certificate indicates who owns the public key contained in the JAR file.


When you sign a JAR file your public key is placed inside the archive along with an associated certificate so that it’s easily available for use by anyone wanting to verify your signature.


To summarize digital signing:



  • The signer signs the JAR file using a private key.

  • The corresponding public key is placed in the JAR file, together with its certificate, so that it is available for use by anyone who wants to verify the signature.

Digests and the Signature File


When you sign a JAR file, each file in the archive is given a digest entry in the archive’s manifest. Here’s an example of what such an entry might look like:
Name: test/classes/ClassOne.class
SHA1-Digest: TD1GZt8G11dXY2p4olSZPc5Rj64=
The digest values are hashes or encoded representations of the contents of the files as they were at the time of signing. A file’s digest will change if and only if the file itself changes.

When a JAR file is signed, a signature file is automatically generated and placed in the JAR file’s META-INF directory, the same directory that contains the archive’s manifest. Signature files have filenames with an .SF extension. Here is an example of the contents of a signature file:


Signature-Version: 1.0
SHA1-Digest-Manifest: h1yS+K9T7DyHtZrtI+LxvgqaMYM=
Created-By: 1.6.0 (Sun Microsystems Inc.)

Name: test/classes/ClassOne.class
SHA1-Digest: fcav7ShIG6i86xPepmitOVo4vWY=

Name: test/classes/ClassTwo.class
SHA1-Digest: xrQem9snnPhLySDiZyclMlsFdtM=

Name: test/images/ImageOne.gif
SHA1-Digest: kdHbE7kL9ZHLgK7akHttYV4XIa0=

Name: test/images/ImageTwo.gif
SHA1-Digest: mF0D5zpk68R4oaxEqoS9Q7nhm60=


As you can see, the signature file contains digest entries for the archive’s files that look similar to the digest-value entries in the manifest. However, while the digest values in the manifest are computed from the files themselves, the digest values in the signature file are computed from the corresponding entries in the manifest. Signature files also contain a digest value for the entire manifest (see the SHA1-Digest-Manifest header in the above example).


When a signed JAR file is being verified, the digests of each of its files are re-computed and compared with the digests recorded in the manifest to ensure that the contents of the JAR file haven’t changed since it was signed. As an additional check, digest values for the manifest file itself are re-computed and compared against the values recorded in the signature file.


You can read additional information about signature files on the Manifest Format page of the JDKTM documentation.


The Signature Block File


In addition to the signature file, a signature block file is automatically placed in the META-INF directory when a JAR file is signed. Unlike the manifest file or the signature file, signature block files are not human-readable.

The signature block file contains two elements essential for verification:



  • The digital signature for the JAR file that was generated with the signer’s private key

  • The certificate containing the signer’s public key, to be used by anyone wanting to verify the signed JAR file

Signature block filenames typically will have a .DSA extension indicating that they were created by the default Digital Signature Algorithm. Other filename extensions are possible if keys associated with some other standard algorithm are used for signing.


Signing JAR Files


Signing JAR Files

You use the JAR Signing and Verification Tool to sign JAR files. You invoke the JAR Signing and Verification Tool by using the jarsigner command, so we’ll refer to it as “Jarsigner” for short.

To sign a JAR file, you must first have a private key. Private keys and their associated public-key certificates are stored in password-protected databases called keystores. A keystore can hold the keys of many potential signers. Each key in the keystore can be identified by an alias which is typically the name of the signer who owns the key. The key belonging to Rita Jones might have the alias “rita”, for example.


The basic form of the command for signing a JAR file is


jarsigner jar-file alias
In this command:

  • jar-file is the pathname of the JAR file that’s to be signed.

  • alias is the alias identifying the private key that’s to be used to sign the JAR file, and the key’s associated certificate.

The Jarsigner tool will prompt you for the passwords for the keystore and alias.


This basic form of the command assumes that the keystore to be used is in a file named .keystore in your home directory. It will create signature and signature block files with names x.SF and x.DSA respectively, where x is the first eight letters of the alias, all converted to upper case. This basic command will overwrite the original JAR file with the signed JAR file.


In practice, you may want to use this command in conjunction with one or more of these options, which must precede the jar-file pathname:






















Jarsigner Command Options
Option Description
-keystore url Specifies a keystore to be used if you don’t want to use the .keystore default database.
-storepass password Allows you to enter the keystore’s password on the command line rather than be prompted for it.
-keypass password Allows you to enter your alias’s password on the command line rather than be prompted for it.
-sigfile file Specifies the base name for the .SF and .DSA files if you don’t want the base name to be taken from your alias. file must be composed only of upper case letters (A-Z), numerals (0-9), hyphen (-), and underscore (_).
-signedjar file Specifies the name of the signed JAR file to be generated if you don’t want the original unsigned file to be overwritten with the signed file.


Example


Let’s look at a couple of examples of signing a JAR file with the Jarsigner tool. In these examples we will assume:

  • your alias is “johndoe”.

  • the keystore you want to use is in a file named “mykeys” in the current working directory.

  • the keystore’s password is “abc123”.

  • the password for your alias is “mypass”.
Under these assumptions, you could use this command to sign a JAR file named app.jar:
jarsigner -keystore mykeys -storepass abc123
-keypass mypass app.jar johndoe

Because this command doesn’t make use of the -sigfile option, the .SF and .DSA files it creates would be named JOHNDOE.SF and JOHNDOE.DSA. Because the command doesn’t use the -signedjar option, the resulting signed file will overwrite the original version of app.jar.


Let’s look at what would happen if you used a different combination of options:


jarsigner -keystore mykeys -sigfile SIG
-signedjar SignedApp.jar app.jar johndoe

This time, you would be prompted to enter the passwords for both the keystore and your alias because the passwords aren’t specified on the command line. The signature and signature block files would be named SIG.SF and SIG.DSA, respectively, and the signed JAR file SignedApp.jar would be placed in the current directory. The original unsigned JAR file would remain unchanged.