Showing posts with label JAR. Show all posts
Showing posts with label JAR. Show all posts

Tuesday, September 18, 2007

HOWTO: setup Java to trust unsigned SSL CERTs

Overview
If you have an application that needs to talk to a web service (or page) that uses SSL, you may get an ugly error the first time you connect.

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target.....


This is probably because you have a self-signed CERT. This is ok and can be dealt with easily following a few simple steps. Yes the following looks like a lot of steps but I was very verbose.... as usual.

Technique
There are a few steps you need to follow to get your JAVA application to trust the self-signed CERT.

Export the Site's CERT
  1. Visit your target URL (web service or whatever) using IE 6.0. I am not sure how to do this using Firefox.
  2. Doubleclick on the "gold lock" symbol at the bottom of the browser.
  3. You will get a "Certificate" window. Select the "Details" tab and click "Copy to File...". A wizard will open
  4. Click "Next" and you will see "Export File Format". Select "Base-64 encoded X.509 (.CER). Click "Next"
  5. Select a filename and location. Click "Next".
  6. Click Finish. You have now saved the cert. The file should look like a block of letters and numbers in a text editor.
Load the CERT into a keystore
There are probably more then one way to do this. I prefer to use a small application I found called portecle. In a few clicks you can create a keystore and import a CERT into it.

Load the keystore of Trusted CERTs
My preferred way is to include a properties file within my JAR and then use that to point to an external keystore (JKS) file.

The following code can be executed at application startup. Once done, it should work for the life of your application.

Properties defaultProps = new Properties();
InputStream in;
try {
in = ArkaProWSClient.class.getResourceAsStream("/mypackage/cert.properties");
defaultProps.load(in);
in.close();
System.setProperty("javax.net.ssl.trustStore",defaultProps.getProperty("javax.net.ssl.trustStore"));
System.out.println("DEBUG: " + defaultProps.getProperty("javax.net.ssl.trustStore"));

} catch (Exception ioex) {
ioex.printStackTrace();
} // end-try-catch
The cert.properties file simply holds the path to the keystore.
javax.net.ssl.trustStore=C:\\certs\\trustcert.jks
This code will
  1. open the properties file which is located in /mypackage/ within the jar
  2. set javax.net.ssl.trustStore system property to the location of my JKS file. This value comes from the cert.properties file.
Now the error will go away and you should be able to access SSL resources. Although I have not tested it fully, I am pretty sure you can fill you keystore with more then one cert allowing you to access many resources from the same application.

Another way to do this is to use an environment variable
java -Djavax.net.ssl.trustStore="C:\certs\trustcert.jks" -jar dist\SSLClient.jar
Final Thoughts
This procedure should allow your application to access SSL protected data that is self-signed. If anyone know how to get the CERT using Firefox, let me know.

Friday, July 6, 2007

HOWTO: load a file from a JAR into a String using JAVA

Overview
In some cases, a SQL creation script may be embedded in a jar. The following will show how to load this file into a usable object (String) for later passing to JDBC.

Technique
The idea is simple. Pass the path to the SQL script following the file structure of the JAR. In this example, "/derbyfun/sql/create.sql" is the file that is being extracted.

To get the contents of the file, the resource is opened as a stream and wrapped as a BufferedReader. The stream is then read, line by line, until end of file. For each line, the text is appended to a StringBuilder. At the end of the method, the StringBuilder is turned back into a string where it can be used in a JDBC call.
public String getResourceFileAsString(String resourcefilename) {
final String newline = System.getProperty("line.separator");
String line = null;
URL url = null;
BufferedReader b = null;
StringBuilder sb = new StringBuilder();
int i = 0;

try {
//
// open buffered reader
//
b = new BufferedReader(
new InputStreamReader(
Main.class.getResourceAsStream(resourcefilename)
)
);

//
// priming read and the loop through rest of file
//
line = b.readLine();
while(line != null) {
//
// add the line to the Stirng Builder ensuring
// the newline is re-added
//
sb.append(line + newline);
//
// just some debug
//
System.out.println("DEBUG: [" + ++i + "] " + line);

//
// read the next line
//
line = b.readLine();
} // end-while

} catch(Exception ex) {
ex.printStackTrace();
} // end-try-catch

return(sb.toString());
}


When the file is ready to be loaded, the following call can be used. In this example, the output is going to standard out. The file is in a sub package called sql which is part of "derbyfun".
System.out.println(
getResourceFileAsString("/derbyfun/sql/create.sql")
);


Final Thoughts
This is pretty straight forward code but may come in handy as a cut/paste for someone who does not remember the syntax... like me.

Friday, June 29, 2007

HOWTO: set the title bar icon for a JAVA Swing Application

Overview
To help polish a JAVA application, it is always nice to have a custom icon that shows up in the left corner of the title bar and in the task list. To add this is simple.

Technique
Say you have a project that is using a package of jliststriping and in your jliststriping directory, you have an icon called a3.JPG. Here is how you would do it..

java.net.URL imgURL = JListStripingForm.class.getResource(
"/jliststriping/a3.JPG"
);
if (imgURL != null) {
this.setIconImage(new ImageIcon(imgURL,"Icon").getImage());
} // end-if
It is done this way so that you can load the icon from a JAR file.

Final Thoughts
This will help add a little polish to your program.

Monday, April 16, 2007

HOWTO: use ANT with JAVA to dynamically create build numbers

Overview
For me, build numbers are very useful. I like to use them where I can so I can keep true to a major, minor, and patch version purpose. The only problem is, how do you automate build numbers in a way that is easy to use in an IDE that doesn't automatically use them? The solution is partially included in ANT and the rest is a little bit of simple project setup.

While you are automating things, why not include simple information about your project bundled with each JAR you create. Including:
  • Program/Library/Project name
  • Author
  • Company/Organization
  • Copyright
  • Description (brief)
  • Version (major/minor/patch)
  • Build Number
  • Build Date
The following will describe the steps for automating ANT to do manage this for you. The example is using Netbeans, however, anything ANT capable should work using this technique.

The process is also being described from a JAVA perspective but there isn't anything truly JAVA specific. For this reason, the technique could be ported to other language. I just happen to like JAVA so that is what I am using.


Technique

What we are doing is simple:
  • Have ANT create/update a small properties file for us in the root of the jar
  • Use a small class or library to open a load this properties file at startup
  • Ensure all data is available through static methods for easy access through-out the program
This setup is done once per project and can then be forgotten about.


build.xml Setup
In Netbeans (and probably other IDEs) build.xml is a place to create your own custom build targets. A target needs to be setup for "-pre-jar" as follows
<!-- Custom Target for AppInfo.java -->
<target name="-pre-jar">
<buildnumber file="buildnumber.properties"/>
<propertyfile file="appinfo.properties"
comment="Everything can be manually updated except buildnum and builddate.">
<entry key="program.PROGNAME" default="${main.class}" />
<entry key="program.AUTHOR" default="" />
<entry key="program.COMPANY" default="" />
<entry key="program.COPYRIGHT" default="now" type="date" pattern="yyyy" />
<entry key="program.DESCRIPTION" default="" />
<entry key="program.VERSION" default="1.0.0" />
<entry key="program.BUILDNUM" value="${build.number}" />
<entry key="program.BUILDDATE" type="date" value="now" pattern="yyyyMMDDHHmmss" />
</propertyfile>
<copy file="appinfo.properties" todir="${build.classes.dir}"/>
</target>

This target can be cut/pasted right into your build.xml as is. It is doing the following:
  • Defines an implementation for -pre-jar to the build system
  • Creates a new buildnumber to be stored in buildnumber.properties.
  • Creates a new propertyfile called appinfo.properties. Within propertyfile many entries are created. All the entries are set to a default that can be updated by hand. These entry tags do not have a value="..." attribute within the tag. The ones with the value="..." will get updated at each build. In this case, the only entry tags affected are BUILDNUM and BUILDDATE.
  • Does a copy of the appinfo.properties file to the build.classes.dir so it can be included in the jar for this project.
After your first build, you will find two new files in the root directory of your project. This is the same directory as build.xml.

buildnumber.properties
This is a file created and maintained by ANT. If you delete it, ANT will create another starting at 1. The file will look something like this.
#Build Number for ANT. Do not edit!
#Sat Apr 14 01:25:36 EDT 2007
build.number=1

With each build, the build.number will be incremented by 1. You do not need to do anything with this file going forward since ANT maintains it.

appinfo.properties
All of the project summary information will be stored in here. After your first build, there isn't much but you can update the static fields as you see fit. The following is a file that was updated for a specific project.

#Everything can be manually updated except buildnum and builddate.
#Sat Apr 14 01:25:36 EDT 2007
program.PROGNAME=LangTrans
program.BUILDNUM=15
program.AUTHOR=Ken Langer
program.DESCRIPTION=This program uses Google Language Tool.(...)
program.BUILDDATE=200704104012536
program.COPYRIGHT=2007
program.COMPANY=StoKen Software
program.VERSION=1.0.0

I manually updated all the fields (using the rules of property files) above except BUILDNUM and BUILDDATE since they get updated dynamically. This is the file that will be included in the JAR output of your project.


Using appinfo.properties
Usage can be done in two ways. You can either roll-your-own, or use a pre-existing library I created.

Roll-Your-Own
Rolling your own is not to bad. Simply open the appinfo.properties file as follows:
InputStream in = null;
Properties props = new Properties();
//
// load properties file
//
try {
//
// get Application information
//
in = getClass().getResourceAsStream("/appinfo.properties");
props.load(in);

// DO SOMETHING HERE WITH THE props object....

in.close();

} catch (IOException ex) {
ex.printStackTrace();
} // end-try-catch

That is it. Accessing the values can be done using the props.getProperty(key); method.

Using Pre-Existing Library
To save me time, I created a simple library (that will get more tools added over time) that has much of this already setup. If you are interested, see stoken-utils. There is a class within the project all AppInfo that you can hand props (from above). It has some simple static accessors you can use for getting the key values you need.

Within the same library, you will see AppInfoPanel which can be stuck into a JFrame for creating a spiffy about box.

Both are used in a sample program I wrote called language-translate. If you look through this program you will see the usage of both.


Either approach above still requires the build.xml configuration but the second one already knows what to do with it after build.xml does its magic.


Final Thoughts
The technique above should allow you to simply and easily include build numbers and other centrally controlled project information.

UPDATE: I just discovered that if you have the compile on save feature in Netbeans 6.5 on, it seems to prevent appinfo.properties from being copied into your build/classes/... folder. This means that any executions within the IDE will probably fail or have errors/exceptions. I will look at a way around this but until then, turn off compile on save and just do a classic SHIFT+F11 to built before a test run.

Wednesday, March 28, 2007

HOWTO: use Netbeans and ANT to auto-run jarsigner

Overview
There are times when you need to sign jar files. In my world it is is all the time since I tend to favor Java WebStart applications. There are techniques using ANT to auto sign JAR files, however, they require you to include your store password which is ok if your code remains internal but may not be so good if you post it to Google Code.

To get around this, there is a pretty easy to implement solution. I, being the Netbeans fan, will describe it from the Netbeans perspective, however, ANT is ANT so it should work using anything.

Description
There is a file within the ANT build process called build.xml. This file is usually located in the root of your project directory. This file lets you create additional targets without directly changing the core build script. Typical usage for me is to add -pre-jar and -post-jar targets. In this case we are going to add a new -post-jar target that will be responsible for signing all the JAR files in the dist directory.

Within the build.xml's <project> open and close tag, I add the following XML blob.
<target name="-post-jar">
<exec dir="${dist.dir}" executable="bulkjarsigner.csh" os="Linux" />
</target>
In this blob you can see a few bits. The main thing is a C-Shell file I wrote, called bulkjarsigner.csh, that has 700 permissions and sits outside my project tree in my personal bin directory (which is in my path).

The script is basic. It gets a listing of all jar files in the dist directory (and sub-directories) and runs jarsigner on it. The following is the script I use (with the obvious passwords changed):

#!/bin/csh
#
#
init:
onintr outahere
set KEYSTORE="~/keystore/my.jks"
set STOREPASS="mystorepassword"
set KEYPASS="mykeypass"
set ALIAS="keyalias"
set FILELIST=`find ./ -print |grep ".jar"`

main:
echo "--- Working out of `pwd` ----"

foreach ARG ($FILELIST)
echo "---- Processing $ARG ----"
jarsigner -storepass $STOREPASS -keypass $KEYPASS -keystore $KEYSTORE $ARG $ALIAS
echo " "
end

set KEYSTORE=""
set STOREPASS=""
set KEYPASS=""
set ALIAS=""

goto pissoff

outahere:
echo " "
echo "User Exit..."

pissoff:
You will note that it does not take any command line args at all. It just takes the current directory specified by ${dist.dir} and gets a listing of all the jar files. foreach jar in the list, it runs jarsigner.

The example above is written in C-SHELL but it could really be any scripting language (even BAT for Windows users).

What You Will See
When you do a build or a clean build, you will see your code compile, be bundled in JAR files and then signed.

That is it. The signed jar files can be verified (jarsigner -verify -verbose...) to confirm that all is well.

Last Thoughts
It is pretty simple to add and remove. It is also handy since you can change the password, alias, keystore,... in one place without having to re-touch every build.xml.
- - -