Another application our team is developing right now is a card access system. The system is quite complex, but the main idea is very simple. User is registered through the web application and receives a card. The card contains access information and when he comes to the door and uses the card, permissions are checked and he is either allowed to open the door or the access is denied.
The web application uses spring
framework (3.2.4) and we use maven as the build tool. The main problem was to
figure out how to communicate with the card through the web browser. Finally we
found out that our only solution is to use java applets. But it’s much easier
said than done.
In this article we’d like to cover
all the steps needed to run java applet which uses clients’ system resources
(such as a smart card reader), which may help you when you decide to use this
deadly combination, too.
JNLP
Suppose, you have an applet built to a jar file called test-applet.jar (you can try to write some simple applet as an exercise).
The recommended way to launch applets on the webpage is by using the Java Network Launch Protocol (JNLP). Our test.jnlp file for this simple example looks like this:
<?xml version="1.0"
encoding="UTF-8"?>
<jnlp spec="1.0+" codebase=""
href="">
<information>
<title>Test applet</title>
<vendor>OKsystem s.r.o.</vendor>
<offline-allowed/>
</information>
<resources>
<!--
Application Resources -->
<j2se
version="1.6+"
href="http://java.sun.com/products/autodl/j2se" />
<jar
href="/SpringAppletTest/applet/test-applet.jar" main="true"
/>
</resources>
<security>
<all-permissions/>
</security>
<applet-desc
name="Test Applet"
main-class="cz.oksystem.spring_applet_test.testapplet.TestApplet"
width="800"
height="550">
</applet-desc>
<update
check="background"/>
</jnlp>
It contains basic information about the
application, path to the .jar file, security information and the applet-desc element to run the applet.
Since
we need our applet to work with a smart card reader, we also need the
permissions to user’s computer resources. That’s why the all-permissions
option is setup (the other possible option is sandbox).
JSP
The next
step is to prepare the applet.jsp
page which uses the jnlp file to run the applet:
<%@page
contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE
html>
<html>
<head>
<meta
http-equiv="Content-Type" content="text/html;
charset=UTF-8">
<script
src="https://www.java.com/js/deployJava.js"> </script>
<title>Test JSP
Page</title>
</head>
<body>
<h1>Hello World!</h1>
<div>
<script>
var attributes = {
code:
'cz.oksystem.spring_applet_test.testapplet.TestApplet', archive: '/SpringAppletTest/applet/test-applet.jar',
width: 800, height: 550};
var parameters = {jnlp_href:
'/SpringAppletTest/applet/test.jnlp', java_status_events: true};
deployJava.runApplet(attributes, parameters, '1.7');
</script>
</div>
</body>
</html>
The core
functionality of the page lies between the script tags.
First, we import the deployJava javascript from the java web page. Deploy-java.js (Deployment Toolkit
script) contains useful functions that can be used to deploy applets in a web
page, in this example the runApplet function. You pass to this function attributes and parameters
containing information about the applet code base, archive which contains the
compiled source and the jnlp location.
If you need to pass some additional parameters that the applet should use, just add them to the parameters object as the key-value pair and use the getParameter() function in your applet java code.
Futher notes
Before we finish this tutorial, we want to point out 2 more issues you would most probably encounter while developing applets for the web applications.
<resources>
<!-- Application Resources -->
<j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se" />
<jar href="/SpringAppletTest/applet/test-applet.jar" main="true" />
<jar href="/SpringAppletTest/applet/some-module.jar" />
</resources>
...
We hope this tutorial helps you at least a bit and we wish you a happy coding.
If you need to pass some additional parameters that the applet should use, just add them to the parameters object as the key-value pair and use the getParameter() function in your applet java code.
Manifest
When you create a JAR file, a default manifest file is created automatically (MANIFEST.MF). It simply contains the “header: value” pairs information about the file. To modify the manifest file, you must first prepare a text file containing the information you wish to add to the manifest.
Our sample manifest file manifest.txt contains following
information:
Permissions: all-permissions
Codebase: *
Application-Name: test-applet
Trusted-Only: true
Trusted-Library: true
Caller-Allowable-Codebase: *
Application-Library-Allowable-Codebase: *
Application-Library-Allowable-Codebase: *
We will not give the full description of the
file properties, because it’s not the aim of this article. You can find all the
possible attributes with their detailed description in the oracle documentation
page:
http://docs.oracle.com/javase/8/docs/technotes/guides/jweb/security/manifest.html
http://docs.oracle.com/javase/8/docs/technotes/guides/jweb/security/manifest.html
Maven manifest
As I have already mentioned in the beginning of this tutorial, we use maven as our build tool for this project. By default, maven archiver generates the manifest file for you. But in this particular situation we need to use our own manifest file that we have created in the previous step. This is done with the <manifestFile> configuration element by setting its value to the location of the manifest file. The content of this file will be merged with the entries generated by Maven Archiver.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/manifest.txt</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Spring-servlet.xml
The only 2 lines you have to add to your usual
spring configuration file are the resources where the applet and javascript are
located:
<mvc:resources mapping="/applet/**"
location="/applet/"/>
<mvc:resources mapping="/js/**"
location="/js/"/> Complete project structure
Signing the applet
At this point, when you build, deploy and run
your web application, the following error is going to appear:
This happens because the applet you are using
have to be signed. To self-sign the applet follow these 3 steps (don’t forget
to use real certificates for production):
1. keytool -genkey -keystore myKeyStore
-alias testuser
2. keytool -selfcert -keystore
myKeyStore -alias testuser
3. jarsigner -keystore myKeyStore
test-applet.jar testuser
Because in this example the applet is self-signed you have to change the java settings to allow running also applications which are not signed by the trusted authority. To do this, go to Control panel -> Java -> Settings -> Security and change the security level to medium.
Because in this example the applet is self-signed you have to change the java settings to allow running also applications which are not signed by the trusted authority. To do this, go to Control panel -> Java -> Settings -> Security and change the security level to medium.
As the note under the security level slider says, “All Java applications will be allowed to run after presenting a security prompt”. I know it’s a very uncomfortable step, but when you realize that the applet has access to your system resources (in our case the card reader connected to the users’ computer), you also realize that this can be a perfect means to attack the clients computer. And that’s the main reason behind it.
After completing
these steps you will be able to successfully deploy and run the application.
Futher notes
After completing these steps you should be able
to run the applet in a spring web application. Similar steps may be used to
make it run on the classic JavaEE platform.
Before we finish this tutorial, we want to point out 2 more issues you would most probably encounter while developing applets for the web applications.
Applet cache
The first issue is the java applet cache. When developing java applets, you may come to a situation when you change some applet code, but when running it in the web browser, nothing changes even when you restart the browser to clear its cache (or clear it manually). The thing about this is a fact, that your browser is not responsible for caching java applets, java does it by itself. The reasons for caching applets are obvious. There is no need for downloading applets every time a user references them, which results also in their startup performance (but sometimes causes headaches to us, programmers).
To clear java cache go to Control panel -> Java -> Settings -> Delete files. Load your web application again and your applet gets fully loaded again, including all of the changes.
Multiple resources in JNLP
The second issue is that sometimes you may need to use multiple resources in your JNLP file. In our case our card reading applet is using a common module with some cryptographic functions implemented there. The solution is to sign the module, build it and add it to the applet folder of your web page. Then reference this jar in resources element in the JNLP file.
...<resources>
<!-- Application Resources -->
<j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se" />
<jar href="/SpringAppletTest/applet/test-applet.jar" main="true" />
<jar href="/SpringAppletTest/applet/some-module.jar" />
</resources>
...
We hope this tutorial helps you at least a bit and we wish you a happy coding.