Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Professional Java.JDK.5.Edition (Wrox)

.pdf
Скачиваний:
31
Добавлен:
29.02.2016
Размер:
12.07 Mб
Скачать

Chapter 14

Option Description

c

This option is simply used to create a new archive.

tThis option will list the table of contents for the archive file. This is a great way to inspect the contents of the JAR file right after you have created it to make sure it was created successfully and the way you anticipated.

Note: The f option is usually combined with the t option to reduce the amount of typing you have to do.

x

This option is used to extract the specified files or all the files from the JAR file.

uThis option allows you to update a JAR file with specified new or changed files. It is more likely that you will use a tool that knows how to update a zip file format or an IDE that can update JAR files for you because this task can be quite cumbersome if you have a lot of files to update.

vThe verbose option allows you to get more feedback from the JAR tool as it creates the JAR. It is very helpful when debugging issues.

f

This option specifies that the JAR file to update is on the command line.

mThis option signifies that you are supplying the JAR tool with a manifest file that is to be included in the JAR.

0The zero option tells the JAR tool to not compress the files and just package them into the archive.

MThis option prevents the default manifest file from being created. Manifest files are optional in JAR files.

iOne of the new features in Java 5, this option is used to generate index information for the JAR file into its META-INF directory under the file named INDEX.LIST.

C [DIR]

This option instructs the JAR tool to change the directory to the one specified and to

 

JAR the files that are being referenced.

Now it is time to show you just how easy it is to create a JAR file. This example will contain two Java files and an images directory. Normally, the Java files would be compiled into classes, and the source code would be removed, but this example simply demonstrates how almost any type of file can be contained in a JAR file. Figure 14-1 shows the directory structure prior to issuing a JAR command.

626

Packaging and Deploying Your Java Applications

 

images

chess

board.bmp

 

W# Chess.java

W# ChessGUI.java

Figure 14-1

Once you know the files and directories you want to archive, you can issue a JAR tool command with the options cvf from the root directory and literally compress the entire chess directory as well as any subdirectories under it. The c option is used to create the archive, the v option specifies verbose, and the f option signifies that you will be supplying the name of the JAR file to create on the command line. Here is an example of the JAR tool in action:

C:\>jar -cvf chess.jar chess added manifest

adding: chess/(in = 0) (out= 0)(stored 0%)

adding: chess/Chess.java(in = 0) (out= 0)(stored 0%) adding: chess/ChessGUI.java(in = 0) (out= 0)(stored 0%) adding: chess/images/(in = 0) (out= 0)(stored 0%)

adding: chess/images/board.bmp(in = 0) (out= 0)(stored 0%)

The chess.jar file is now created and contains all the files under the C:\chess directory. There is a default manifest file that was automatically generated by the JAR tool in the META-INF directory of the JAR file. It contains nothing more than a version string. Figure 14-2 shows the new JAR structure.

 

 

images

chess

 

board.bmp

 

 

W#

Chess.java

 

W#

ChessGUI.java

meta-inf

Manifest.mf

Figure 14-2

627

Chapter 14

You can also use the JAR tool to see the contents of the chess.jar file by specifying the t option on the file. Here is an example of how to view the table of contents of a JAR file:

C:\>jar -tf chess.jar META-INF/ META-INF/MANIFEST.MF chess/

chess/Chess.java

chess/ChessGUI.java

chess/images/

chess/images/board.bmp

Besides viewing the contents of a JAR file, you can also extract the contents of the JAR file. This may be necessary if you ever get into a situation when you need to unpack the JAR to patch or edit files in the JAR file. To extract a JAR file, you will need to specify the x option. In this example, the xvf options are used. Refer to the option table in this section for more information on options and their uses:

C:\>jar -xvf chess.jar created: META-INF/

inflated: META-INF/MANIFEST.MF created: chess/

extracted: chess/Chess.java extracted: chess/ChessGUI.java

created: chess/images/ extracted: chess/images/board.bmp

The command simply extracts the JAR file to the current working directory. Now you can edit the files and repackage them if need be.

Examining the Basic Manifest File

The manifest file can be thought of as a file that contains meta data information about the JAR file it belongs to. By using the manifest file, you can version control, digitally sign, and seal the JAR files, packages, and extensions. When you first create your JAR file, if you didn’t specify the -M option, a default manifest will be created for you. The M option prevents the default manifest file from being created. The default manifest file looks something like this, depending on the version of Java you are using:

Manifest-Version: 1.0

Created-By: 1.5.0 (Sun Microsystems Inc.)

The manifest file is broken up into two general parts: a main section and an individuals section where information about different files or packages can be listed. You don’t have to list every file you have in the JAR file in the manifest file. In fact, you don’t have to list any unless you plan to sign particular files in the JAR file. If you do, then those files must be listed.

628

Packaging and Deploying Your Java Applications

Information in the manifest is broken up by name-value pair entries. The colon (:) character is used to separate the name from the value. This is similar to property files except for, in property files, the delimiter is an equals (=) sign. Any attributes that Java can’t understand are ignored, but the attributes can still be used by the application. Therefore, these attributes are sometimes referred to as application-specific attributes. The following table describes several of the most common main attributes you will run across and gives a brief description of each.

Attribute

Description

 

 

Manifest-Version

The value of this attribute is the manifest file version.

Created-By

Generated by the JAR tool, this is the version of Java that was used to cre-

 

ate the JAR. It also includes the name of the vendor who created the Java

 

implementation.

Signature-Version

The value of this attribute contains the signature version of the JAR file and

 

must contain a valid version number string with this specific format:

 

digit+{.digit+}*

Class-Path

The class loader uses this value to create an internal search path that will

 

look for extensions or libraries that this application needs. URLs are sepa-

 

rated by spaces.

Main-Class

This attribute is needed if you are creating a self-executing JAR file. You

 

need to specify the name of the class file that contains the main method.

 

When you specify the name, do not include the .class extension, or your

 

JAR will not execute.

Sealed

This attribute has only two possible values: true or false. If true, all the

 

packages in the JAR file are sealed unless they are defined individually to

 

be different.

 

 

Though the manifest is not a very exciting file to read about, it definitely is worth exploring so that you have a general understanding of the power and flexibility it provides JAR files with.

Examining Applets and JARs

One of the most common uses for JAR files is to bundle applet code inside of JAR files and make them accessible, like any other applet via a Web browser. Because of this feature, a special attribute called an extension in the manifest can be used to incorporate other packages in your applets. For more information on applets, see the “Analyzing Applets” section within this chapter.

Here is a list of the extension attributes that can be used to optimize your applets.

629

Chapter 14

Attribute

Description

 

 

Extension-List

This attribute is where you list the optional packages

 

that you would like to include in your applets. The

 

package names should be separated by a single

 

space.

(extension)-Extension-Name

The unique name of the package that the Java plug-

 

in will use to determine if the package is installed is

 

stored in this attribute.

(extension)-Specification-Version

This attribute lets the Java plug-in know which is the

 

minimum version required of the package to use.

(extension)-Implementation-Version

This attribute lets the Java plug-in know which is the

 

minimal version of the package that is required. If

 

the version is too old, the plug-in will attempt to

 

download a newer version of the package.

(extension)-Implementation-Vendor-Id

This attribute is used to assign a vendor ID to the

 

optional package. Again, the Java plug-in will com-

 

pare the vendor IDs to make sure it is getting the

 

correct optional package.

(extension)-Implementation-URL

In order for the Java plug-in to know where to get

 

the latest version of the package, this attribute

 

would have to be set with the URL that tells the

 

Java plug-in where to download the latest optional

 

package.

 

 

Signing JAR Files

Signing JAR files is important for security-aware applications. It ensures that the JAR file has not been tampered with and the file is from the original author. JAR files are signed using a special utility tool called jarsigner, which can be found in your JAVA_HOME/BIN directory. JAR files can also be signed by using the java.security API via code. The jarsigner tool signs the JAR files by accessing a keystore that has been created by the keytool utility that is used to create public and private keys, issue certificate requests, import certificate replies, and determine if public keys belonging to third parties are trusted. The private key is used to sign the JAR file by the jarsigner tool, and only people who know the private key’s password can sign the JAR file with it.

When a JAR file is signed by the jarsigner tool, all of the entries in the META-INF directory are signed. Even nonsignature-related files will be signed. Generally speaking, signature-related files end in the following extensions: *.RSA, *.SF, *.DSA, and SIG-*.

You can sign the JAR file using the Java.security API; however, compared to using the jarsigner tool, there will be a lot more work for you to do. When a JAR file is successfully signed, it must contain an updated manifest file, signature file, and signature block file. Entries for each file signed are created in the manifest file and look like the following example:

Name: com/wrox/SampleSigned.class

SHA1-Digest: fcavHwerE23Ff4355fdsMdS=

630

Packaging and Deploying Your Java Applications

Now that you know the theory about JAR signing, it is time to show you a concrete example of how to sign a JAR and use all the wonderful tools that the Java SDK provides you with. Note that all these tests will not be with valid certificates or keystores; rather, it will be example keystores that you will create for testing purposes. This is great when you need to develop applications that require you to sign JAR files but don’t have access to a certificate or keystore. The following example will show you how to use the keytool to generate a keystore and create a self-signed test certificate that you can use with the jartool to sign the chess.jar file that you created earlier in this chapter.

The first thing you want to do is create a keystore that you can use for creating a self-signed certificate. The following are the steps involved in generating the key:

1.Execute the keytool as shown. This will create a myKeystore file that will contain your key:

C:\>keytool -genkey -keystore myKeystore -alias myself

2.It will prompt you to enter a password for the keystore. Simply enter password:

Enter keystore password: password

3.Next, you will be asked to fill in several lines of data about yourself. Here is what you enter to generate the key:

What is your first and last name? [Unknown]: John Doe

What is the name of your organizational unit? [Unknown]: IT

What is the name of your organization? [Unknown]: Wrox

What is the name of your City or Locality?

[Unknown]: Springfield

What is the name of your State or Province? [Unknown]: Ohio

What is the two-letter country code for this unit? [Unknown]: US

Is CN=John Doe, OU=IT, O=Wrox, L=Springfield, ST=Ohio, C=US correct? [no]: Yes

4.The last step is to enter a password for the private key. Here, you’ll see the word password entered again:

Enter key password for <myself>

(RETURN if same as keystore password): password

Your new myKeystore file should be generated. You can open it up and view it in a text editor if you want, but the majority of the contents are encrypted. Even though you have a keystore, you still cannot sign a JAR file until you have a certificate that you can use for signing. Fortunately, the keytool is able to generate a self-signed certificate for you. This is simply done by issuing the following command:

C:\>keytool -selfcert -alias myself -keystore myKeystore

631

Chapter 14

This command will prompt you for your keystore password. When you created the keystore, you made it using the word password as your password so that is what you should enter. This command can sometimes take a minute or two to complete, depending on your system:

Enter keystore password: password

You now have a certificate and are ready to sign the JAR file. However, how do you know for sure that the certificate and the keystore are okay? The easiest way is to issue a keytool command with the option -list on the command line. This will display the contents of the keystore. Here is the output of the command:

C:\>keytool -list -keystore myKeystore

Enter keystore password: password

Again, you have to enter your password to access the information in the keystore. The output after entering your password is shown in the following example:

Keystore type: jks

Keystore provider: SUN

Your keystore contains 1 entry

myself, Jul 21, 2004, keyEntry,

Certificate fingerprint (MD5): 96:0B:2C:20:EA:DB:87:7A:64:DA:9F:68:21:85:B6:9A

The output shows the type of keystore you are using, the provider, and the certificate fingerprint. If you get the above printout, you are ready to sign the JAR file. In order to sign the JAR file, you must now use the jarsigner tool. Taking the keystore you generated earlier, issue the following command at a command prompt:

C:\>jarsigner -keystore myKeystore chess.jar myself

Enter Passphrase for keystore: password

Warning: The signer certificate will expire within six months.

You have now successfully signed your first JAR file! To verify that the jarsigning tool successfully signed the JAR file that you specified, extract the JAR file and review its contents. You should now see two new files in the JAR file: one called Myself.dsa and the other called Myself.sf. The .dsa (digital signature) file is unreadable, but the .sf file can be read. The contents of it are shown in the following example:

Signature-Version: 1.0

Created-By: 1.5.0 (Sun Microsystems Inc.)

SHA1-Digest-Manifest-Main-Attributes: XpKykodQ7e3bKKW8wqLFO8VocOU=

SHA1-Digest-Manifest: eL4xJ2eU5oyO7h4VVYW0hs1pEj0=

Name: chess/images/board.bmp

SHA1-Digest: wvxwx9Dqd+jbKoe8e7raVxSfNzI=

Name: chess/ChessGUI.java

SHA1-Digest: JlWKkQ9l5/82bHxMdf4nzrmphH0=

Name: chess/Chess.java

SHA1-Digest: Y4jUlkFH64RojRERTRBEIZRC+uc=

632

Packaging and Deploying Your Java Applications

These three new entries show the signature for each of the files that were signed by the jarsigner. These entries are now also shown in the manifest.mf file:

Manifest-Version: 1.0

Created-By: 1.5.0(Sun Microsystems Inc.)

Name: chess/images/board.bmp

SHA1-Digest: 2jmj7l5rSw0yVb/vlWAYkK/YBwk=

Name: chess/ChessGUI.java

SHA1-Digest: 2jmj7l5rSw0yVb/vlWAYkK/YBwk=

Name: chess/Chess.java

SHA1-Digest: 2jmj7l5rSw0yVb/vlWAYkK/YBwk=

Another way to verify that the jarsigner signed the JAR file correctly is to run the jarsigner tool with the -verify option on the JAR file you want to verify. So, go ahead and issue the following command on the JAR file you just signed:

C:\>jarsigner -verbose -verify chess.jar

You should see the following output if it was successful:

 

289

Wed July

21

21:28:58 EDT

2004

META-INF/MANIFEST.MF

 

410

Wed July

21

21:28:58 EDT

2004

META-INF/MYSELF.SF

 

1008

Wed July

21

21:28:58 EDT

2004

META-INF/MYSELF.DSA

 

0

Wed July

21

13:36:18 EDT

2004

META-INF/

 

0

Wed July

21

13:27:02

EDT 2004 chess/

sm

0

Wed July

21

13:26:32

EDT 2004 chess/Chess.java

sm

0

Wed July

21

13:26:42

EDT 2004 chess/ChessGUI.java

 

0

Wed July

21

13:27:14 EDT

2004

chess/images/

sm

0

Wed July

21

13:27:08 EDT

2004

chess/images/board.bmp

 

s = signature was verified

 

 

 

 

m = entry is listed

in manifest

 

 

 

 

k = at least one certificate was

found in keystore

 

i = at least one certificate was

found in identity scope

jar verified.

If the validation failed, the jarsigner tool would either throw a security exception, or, if the JAR file was not signed at all, it would send a message back stating that the JAR file is unsigned (signature missing or not parsable).

If you have made it through all of these steps, congratulations! You now know how to sign your own JAR files. This is critical when you need to ensure security on a JAR file. JAR files are generally signed when using Java Web Start applications and especially applets, but signing can definitely be done for all the JAR files you create.

JAR files can also be signed by multiple people. What will happen is the signatures for each of the people who ran the jarsigner tool will be stored in the META-INF directory just as is the case when one person signs it. You can even sign the JAR file with different versions of the JDK so that there are a lot of

633

Chapter 14

security options you can do using the tools that have been mentioned for signing JAR files and creating keystores. Before moving on, take a closer look at the options that can be used with the jarsigner tool.

Option

Description

 

 

keystore <url>

This option is required when signing a JAR file and will default

 

to the .keystore file in your user.home directory if you do not specify

 

the keystore file to use. You can specify a full path and filename

 

of the keystore file for the URL parameter.

storepass <password>

This is used to supply the password that is required to access the

 

keystore you plan to use when signing your JAR file.

storetype <storetype>

This is used to specify the keystore type to be used. The security

 

.properties file has an entry called keystore.type, and the jarsigner

 

tool will default to that value if no storetype is provided.

keypass <password>

This is your password for your private key if it is different from the

 

store password. If you don’t supply this option, you will be

 

prompted for the password, if necessary.

sigfile <filename>

This specifies the base of the filename to use for generating the .sf

 

and .dsa files. This option allows you to override the default values

 

generated by the jarsigner tool.

signedjar <filename>

You can specify another name for the JAR file that will be signed. If

 

you don’t specify a name, the JAR file you are issuing the command

 

on is overwritten. For example, you could use chess_secure.jar for the

 

name if you want to have signed and unsigned copies of chess.jar.

verify <jarfile>

This is an option for verifying that the JAR file is signed properly.

verbose

Verbose tells the jarsigner tool to output more information during the

 

signing process to help with debugging issues.

certs

This option should be used with verbose and verify together. It will

 

display certificate information for each signer of the JAR file.

tsa <url>

This allows you to specify the location of the Time-Stamping

 

Authority.

 

 

Examining the JAR Index Option

Downloading JAR files that are required by applets can be slow and painful, and searching them for the appropriate classes they contain used to be very linear. Linear searching of a JAR file for its class can result in slow performance, wasted bandwidth, and waiting too long to initiate a download of a JAR file the applet may be missing. With the JARIndex algorithm, all the JAR files in an applet can be stored into an index file, which thus makes class loading times much faster — especially in determining what needs to be downloaded.

634

Packaging and Deploying Your Java Applications

The jar tool has a new option, -i, which means index. This option will generate index information about the classes, packages, and resources that exist inside the JAR file. This makes access times much

quicker. The information is stored in a small text file under the META-INF directory called INDEX.LIST. When the JAR is accessed by the class loader, it reads the INDEX.LIST file into a hash map that will contain all the files and package names in the hash map. Instead of searching linearly in the JAR file for the class file or resource that the class loader needs, it can now query the hash map, resulting in quicker access times. The INDEX.LIST file is always trusted by the class loader, so manipulating it manually is not wise. If you make a mistake and the class loader can’t locate a resource or file, it will throw an InvalidJarIndexException so that you can capture the error and correct it. You can generate an index of the JAR file chess.jar that you created in previous examples by issuing the following command:

C:\>jar -iv chess.jar

The contents of the JAR file now contain an INDEX.LIST file in the META-INF directory:

C:\>jar -tf chess.jar

META-INF/INDEX.LIST

META-INF/ META-INF/MANIFEST.MF chess/ chess/Chess.java chess/ChessGUI.java chess/images/ chess/images/board.bmp

The INDEX.LIST file contains the following information:

JarIndex-Version: 1.0

chess.jar chess chess/images

The INDEX.LIST file is simply text and is compressed inside the JAR file, so the memory footprint of the INDEX.LIST file is very light, to say the least.

Creating an Executable JAR

Java supports the ability to make JAR files executable. If a JAR file is executable, it can be run from a console or command prompt by typing:

java –jar jar-file-name

Also, if you are in Windows and your application is GUI-driven, simply double-click an executable JAR, and it will automatically run.

635

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]