Deploying a Single JAR

In order to deploy an application to the Java Warehouse, it must be packaged as a single JAR file. We've already discussed packaging Jython applications into a JAR file using the Jython standalone method in Chapter 13. In this section, you will learn how to make use of the One-JAR (http://one-jar.sourceforge.net/) product to distribute client-based Jython applications. In order to get started, you will need to grab a copy of One-JAR. There are a few options available on the download site, but for our purposes we will package an application using the source files for One-JAR. Once downloaded, the source for the project should look as follows.

Listing 17-10. src com simontuffs onejar

Boot.java Handler.java IProperties.java JarClassLoader.java

This source code for the One-Jar project must reside within the JAR file that we will build. Next, we need to create separate source directories for both our Jython source and our Java source. Likewise, we will create a separate source directory for the One-Jar source. Lastly, we'll create a lib directory into which we will place all of the required JAR files for the application. In order to run a Jython application, we'll need to package the Jython project source into a JAR file for our application. We will not need to use the entire jython.jar, but rather only a standalone version of it. The easiest way to obtain a standalone Jython JAR is to run the installer and choose the standalone option. After this is done, simply add the resulting jython.jar to the lib directory of application. In the end, the directory structure should resemble the following.

Listing 17-11.

one-jar-jython-example java lib jython.jar LICENSE.txt onejar src com simontuffs onejar

Boot.java Handler.java IProperties.java JarClassLoader.java one-jar-license.txt src

As you can see from the depiction of the file structure in this example, the src directory will contain our Jython source files. The LICENSE.txt included in this example was written by Ryan McGuire (http://www.enigmacurry.com). He has a detailed explanation of using One-Jar on his blog, and we've replicated some of his work in this example. . .including a version of the build.xml that we will put together in order to build the application. Let's take a look at the build file that we will use to build the application JAR. In this example we are using Apache Ant for the build system, but you could choose something different if you'd like.

Listing 17-12. build.xml

<project name="JythonSwingApp" default="dist" basedir=".">

<!-- ################################################# These two properties are the only ones you are likely to want to change for your own projects: --> <property name="jar.name" value="JythonSwingApp.jar" /> <property name="java-main-class" value="Main" /> <!-- ################################################## -->

<!-- Below here you don't need to change for simple projects -->

<property name="src.dir" location="src"/>

<property name="java.dir" location="java"/>

<property name="onejar.dir" location="onejar"/>

<property name="java-build.dir" location="java-build"/>

<property name="build.dir" location="build"/>

<property name="lib.dir" location="lib"/>

<path id="classpath">

<fileset dir="${lib.dir}" includes="**/*.jar"/> </path>

<target name="clean"> <delete dir="${java-build.dir}"/> <delete dir="${build.dir}"/> <delete file="${jar.name}"/> </target>

<target name="dist" depends="clean"> <!-- prepare the build directory -- > <mkdir dir="${build.dir}/lib"/>

<mkdir dir="${build.dir}/main"/> <!-- Build java code --> <mkdir dir="${java-build.dir}"/>

<javac srcdir="${java.dir}" destdir="${java-build.dir}" classpathref="classpath"/> <!-- Build main.jar -- >

<jar destfile="${build.dir}/main/main.jar" basedir="${java-build.dir}"> <manifest>

<attribute name="Main-Class" value="Main" /> </manifest> </jar>

<delete file="${java-build.dir}"/> <!-- Add the python source --> <copy todir="${build.dir}">

<fileset dir="${src.dir}"/> </copy>

<fileset dir="${lib.dir}"/> </copy>

<javac srcdir="${onejar.dir}" destdir="${build.dir}" classpathref="classpath"/> <!-- Copy the OneJar license file -- >

<copy file="${onejar.dir}/one-jar-license.txt" tofile="${build.dir}/one-jar-license.txt"

<jar destfile="${jar.name}" basedir="${build.dir}"> <manifest>

<attribute name="Main-Class" value="com.simontuffs.onejar.Boot" /> <attribute name="Class-Path" value="lib/jython-full.jar" /> </manifest> </jar>

<delete dir="${java-build.dir}" /> <delete dir="${build.dir}" /> </target>

Because this is a Jython application, we can use as much Java source as we'd like. In this example, we will only use one Java source file Main.java to "drive" our application. In this case, we'll use the PythonInterpreter inside of our Main.java to invoke our simple Jython Swing application. Now let's take a look at the Main.java source.

Listing 17-13. Main.java import org.python.core.PyException; import org.python.util.PythonInterpreter;

public class Main {

public static void main(String[] args) throws PyException{ PythonInterpreter intrp = new PythonInterpreter(); intrp.exec("import JythonSimpleSwing as jy"); intrp.exec("jy.JythonSimpleSwing().start()");

Now that we've written the driver class, we'll place it into our java source directory. As stated previously, we'll place our Jython code into the src directory. In this example we are using the same simple Jython Swing application that we wrote for Chapter 13.

Listing 17-14. JythonSimpleSwing.py import sys import javax.swing as swing import java.awt as awt class JythonSimpleSwing(object):

self.frame=swing.JFrame(title="My Frame", size=(300,300))

self.frame.defaultCloseOperation=swing.JFrame.EXIT_ON_CLOSE;

self.frame.layout=awt.BorderLayout()

self.panel1=swing.JPanel(awt.BorderLayout())

self.panel2=swing.JPanel(awt.GridLayout(4,1))

self.panel2.preferredSize = awt.Dimension(10,100)

self.panel3=swing.JPanel(awt.BorderLayout())

self.title=swing.JLabel("Text Rendering")

self.button1=swing.JButton("Print Text", actionPerformed=self.printMessage) self.button2=swing.JButton("Clear Text", actionPerformed=self.clearMessage) self.textField=swing.JTextField(30) self.outputText=swing.JTextArea(4,15)

self.panel1.add(self.title)

self.panel2.add(self.textField)

self.panel2.add(self.button1)

self.panel2.add(self.button2)

self.panel3.add(self.outputText)

self.frame.contentPane.add(self.panel1, awt.BorderLayout.PAGE_START) self.frame.contentPane.add(self.panel2, awt.BorderLayout.CENTER) self.frame.contentPane.add(self.panel3, awt.BorderLayout.PAGE_END)

def start(self):

self.frame.visible=1

def printMessage(self,event): print "Print Text!" self.text = self.textField.getText() self.outputText.append(self.text)

def clearMessage(self, event): self.outputText.text = ""

At this time, the application is ready to build using Ant. In order to run the build, simply traverse into the directory that contains build.xml and initiate the ant command. The resulting JAR can be run using the following syntax: java -jar JythonSwingApp.jar

In some situations, such as deploying via web start, this JAR file will also need to be signed. There are many resources online that explain the signing of JAR files that topic will not be covered in this text. The JAR is now ready to be deployed and used on other machines. This method will be a good way to package an application for distribution via the Java Store.

0 0

Post a comment

  • Receive news updates via email from this site