• No results found

Why an extra tool? Apache ant. Actually, So, what is ant? Why not just the IDE? Flexibility! An essential tool for Java development

N/A
N/A
Protected

Academic year: 2021

Share "Why an extra tool? Apache ant. Actually, So, what is ant? Why not just the IDE? Flexibility! An essential tool for Java development"

Copied!
16
0
0

Loading.... (view fulltext now)

Full text

(1)

Apache ant

An essential tool for Java

development

1

Why an extra tool?

• Why ant?

Wouldn’t NetBeans (or Eclipse) suffice?

• IDEs like NetBeans are structured to help build certain types of applications

– Standard Java (SE) applications

– Web-style with servlets/JSPs/JSFs; IDE deploying built application to local web-container (Tomcat or web-container of glassfish)

– EJB applications; IDE deploying built application to container (glassfish or other)

• Not so well suited to building systems involving arbitrary multiple processes running on different machines.

2

Why not just the IDE? Flexibility!

• For complicated client-server setups, and some other

tasks, need more flexibility

– “scripts” to build client/server/support applications

• Each involving own codebase but sharing some framework code

– “scripts” deploying applications

• May need to copy files to different locations and organize them in particular directories

– “scripts” to start/stop server, support, client applications as processes on different machines

– Separate console sessions so can observe demonstration tracer output from different processes

• Scripts? – Ant “buildfiles”

3

Actually, …

• The IDEs use ant as a build tool anyway

– build file gets generated by IDE with “targets” to compile application and run it

• And extra “targets” as needed to do things like deploy an application onto a Tomcat webserver

• You can add “targets” to the IDE’s build file

– But still limited in viewing and controlling different processes, and no easy way to deploy onto different machines.

• If you have a project originally developed outside of the IDE that has an ant build.xml file, you can import it into the IDE and use your defined build options rather than the standard IDE ones.

4

So we will use ant to build and deploy RMI,

CORBA and other applications

• Can continue to use IDE to prepare code

– Will usually need to copy directories with generated .class files and employ these from ant script

• Use ant build files to build and run applications.

– Often cannot run conveniently from inside IDE so start separate terminal sessions, cd to "dist" directories created by IDE's own ant script and run .jar files created in IDE's build step

• When get to EJBs, where IDE has integrated

support with its own extra "targets" in its

generated ant build.xml file, we will revert to

using just the IDE

5

So, what is ant?

(2)

Apache ant

• “Apache Ant is a Java-based build tool.

– it is kind of like Make, but without Make's wrinkles.” • “Why another build tool?”

– Make-like tools are shell-based • Evaluate a set of dependencies, • Execute commands as for a shell.

– Can extend these tools by using or writing any program for the OS that you are working on. But very OS dependent.

• “Makefiles are inherently evil as well.”

– Make dates from the 1970s; it may be Unix-guru friendly but is quite hostile to those not of that fraternity

– It is pernickety about details of format, obscure, depends on default make rules (that often differ on different platforms), has obscure conventions

– Essentially, part of the initiation rights of the Unix elite

All quotes from the introduction to ant at the apache.org site 7

A build tool

• As a build tool, ant uses some concepts that are similar to those in make

– Properties can be defined • Referenced in actual build steps

• Define things like library paths, load time flags, etc – Several “targets”

• A makefile, or an ant build.xml file, will usually define several targets – “.exe” build the program, “clean” remove junk left by compiler, … • When invoked, make or ant is told which target to work on – Dependencies

• Some “targets” depend on other work, defined in other targets, having been successfully completed first

– Typical makefile – link step implicit (or explicit) dependence on compile step – Integration with version management systems

• Make understands how to extract files from SCCS version management systems; ant understands CVS, subversion, …

8

Generic build “script”

Define property 1 Define property 2

Associate symbolic name with particular collection of files Target-1

What does it depend on? How do you “build” it?

(compile?, link?, copy files?, create archive?, …) Target-2

9

Makefiles and build.xml

• Makefile

– Obscure syntax

– Employs shell like constructs –with a slightly changed syntax that causes problems for the naïve user

– Format sensitive

– Can have targets that involve starting applications as separate processes, (start server, pause, start client), but these not readily defined

• Build.xml

– Well defined structure

• XML document!

– Easy to specify targets with parallel and sequential subtasks 10

Running a build tool – remember make

make

– Looks for the file makefile or Makefile

– Identifies the default target (the first target in a makefile) – Determines whether there are other targets on which this default

target depends

• If there are, recursively searches for further dependencies

– Works out an order for performing the build steps

• Determined via the recursive search through dependency tree – a kind of post-order traversal

– Runs the required compile, link etc steps

make MyApp.cgi

– Looks for the file makefile or Makefile – Finds the specified target "MyApp.cgi" – Builds as described above for the default target

11

Build dependencies

• Target-A depends on

+ Target-B, which depends on

+ Target-B1

+ Target-B2, which depends on

+ Target-B2-i + Target-B2-ii

+ Target-C

• Build order:

– B1, B2-i, B2-ii, B2, C, A

12
(3)

Running ant

ant [options] target

– Looks for the file build.xml

– Finds the specified target

– Recursively searches for other targets on

which desired target depends

– Works out an order for performing the build

steps (post-order traversal of dependency

tree)

– Runs the required steps

Can specify more than one target, ant does them in turn 13

Some of ant's options

• -projecthelp, -p print project help information • -version print the version information and exit • -diagnostics print information that might be helpful to

diagnose or report problems. • -quiet, -q be extra quiet • -verbose, -v be extra verbose • -debug, -d print debugging information

• -lib <path> specifies a path to search for jars and classes • -noinput do not allow interactive input

• -buildfile <file>, -file <file>. -f <file> use given buildfile • -D<property>=<value> use value for given property

14

ant

Buildfile elements

15

Project

• An ant “buildfile” (by default named build.xml) is

an XML document

• Top level element is

project

<?xml Version='1.0' ?>

<project …>

<!--Here define the properties and targets for the project

-->

</project>

• For you, a project would be an assignment with

targets like “compile-server”, “compile-client”,

“run-server”, “clean”, …

16

Project

• The Project element should have

attributes

– name

name of project

– default

default target

– basedir

base directory

(typically your build.xml file will be in your project's "home" directory so basedir='.')

• Example

<project name="rmi-demo" default="build" basedir=".">

17

Properties

• Name=value pairs; properties referenced later in tasks performed for various targets.

– In some ways, like environment variables or command line arguments for applications

• Example

– Context

• Several of the RMI examples in our RMI section use a copy of the rmiregistry (naming lookup) program

• They need to run it at a non-standard port (standard port should be reserved for an rmiregistry handling deployed applications, it shouldn't be used when developing and testing applications – because you need to restart your rmiregistry each time a test application is redeployed!)

<propertyname="APORT" value="13456" />

And later as part of a "run-…" target get the task

<exec executable="rmiregistry" > <arg value="${APORT}" /> </exec>

Start rmiregistry on chosen port

(4)

Targets

• Targets – things you want done!

• A target has a number of attributes and a

"body" that contains the specification of

the actions that must be performed when

ant is told to build that target.

19

Target attributes

Attribute Description Required

name the name of the target. Yes

depends a comma-separated list of names of targets on which

this target depends. No

if the name of the property that must be set in order for

this target to execute. No

unless the name of the property that must not be set in order

for this target to execute. No

description a short description of this target's function. No

20

Target attributes

• "name" – identifies specific target

• "description" –

– Explanatory information

• Someone new to project can run ant –projecthelp, will get back a list of the targets and what each one does

– Can leave out description if target is simply some low-level sub-task that wouldn't be of interest to a person developing or maintaining the project

• "depends" –

– Information needed to build that dependency tree and hence work out order for build steps.

• Conditionals – if / unless

– Targets that may not need to actually be run

21

<target …>

body

</target>

• The body defines the processing tasks

that must be executed to "build" the given

target.

• Tasks?

– Compile a file

– Copy a file

– Combine several files into an archive

– Run a specific executable

– …

22

Tasks

• Ant is extendable

– The ant program reads target descriptions and runs the listed tasks.

• Some tasks are defined by code in ant itself

– Tasks defined as classes in the ant.jar file – Things like

• echo – print a progress (or warning) message • javac – compile a .java file

• exec – run some named executable • jar – create a Java archive file

23

Optional tasks

• There are many "optional tasks"

– Essentially, these are additional classes

packaged in a .jar file

– If you want to use these optional tasks, you

must download the appropriate .jar file (from

apache.org) and install it somewhere that is

accessible to the ant program

• /lib directory of ant installation • ${user.home}/.ant/lib

(5)

Optional tasks

• .NET Tasks

– Compile C# code etc

• SourceOffSite

– Get source code for project files from some remotely hosted Microsoft Visual Source Safe system

• Telnet

– Run a script of shell commands after logging in to a remote timeshare system

• JUnit

– Run some JUnit unit tests

• XmlValidate

– Check XML documents against DTD specifications

• …

25

Your tasks

• You can even write your own Java classes

that can be integrated with ant

– E.g. you have to use some academic's purist

functional programming language in your

project

• Define a Java class that invokes file manipulations and process-sublaunch steps to perform the various arcane steps needed to prepare and run a program in this language

• Subsequently have ant scripts that automate the rigmarole by invoking this task

http://ant.apache.org/manual/tutorial-writing-tasks.html

26

Common

core

tasks

• LoadProperties

– Sometimes better to keep all those name=value property definitions separate from the real build.xml file – A <loadproperties …>…</loadproperties> task can pull in that file and define the properties • Mkdir

– Makes a directory

• E.g. don't want compiled .class files in with source, instead wish to place them in some build directory – Better make that directory

• Copy

– Copy specified file between directories • Property

– Define a single property • Javac

– Compile java file

• GUnzip/Gzip, Jar, Zip/Unzip, Tar/Untar – Manipulate archive files • Rmic

– Run rmi compiler (for older style Java RMI applications) • Sequential

– Group other tasks and run in order • Parallel

– Has set of Sequential subtasks – creates separate threads/processes to run these

27

Examples

“No, no! The adventures first,” said the Gryphon in an impatient tone: “explanations take such a dreadful time.”

28

First example

Apache ant's own "HelloWorld"

http://ant.apache.org/manual/tutorial-HelloWorldWithAnt.html 29

Apache's "Hello world" with ant

• The program:

package oata;

public class HelloWorld {

public static void main(String[] args) { System.out.println("Hello World"); }

}

• In file in ./src/oata/HelloWorld.java

Without ant, simple compile and run:

mkdir build; mkdir build/classes

$ javac -sourcepath src -d build/classes src/oata/HelloWorld.java $ java -cp build/classes oata.HelloWorld

Hello World

(6)

oata/HelloWorld

• What about an executable .jar file?

– Not really needed for a HelloWorld application but if you did have a real application with many classes it is more "polite" to package and distribute it as an executable .jar file.

• Need to provide "manifest" including name of

class with public void main(String[])

• Need to copy this into newly created .jar file

along with the code.

• Place .jar file in build/jar subdirectory

(conventional)

31

.jar file part of example

1. $ cat > myManifest <<% 2. >Main-Class: oata.HelloWorld 3. >% 4. $ cat myManifest 5. Main-Class: oata.HelloWorld 6. $mkdir build/jar

7. $jar cfm build/jar/HelloWorld.jar myManifest -C build/classes .

8. $java -jar build/jar/HelloWorld.jar 9. Hello World

1..3 Create the myManifest with the specified content (using Unix "here" document!) 4..5 Check it was done right!

6 Make the build/jar subdirectory

7 Create a new jar file, with data from the myManifest file, and classes from build/classes 8..9 Run the application from the .jar file version

32

Of course, it's all different on a

different OS

md build\classes

javac -sourcepath src -d build\classes src\oata\HelloWorld.java java -cp build\classes oata.HelloWorld

echo Main-Class: oata.HelloWorld>myManifest md build\jar

jar cfm build\jar\HelloWorld.jar myManifest -C build\classes . java -jar build\jar\HelloWorld.jar

33

Ant first build file

<project name='oata Hello World' >

<target name="clean" description='Tidy up' > <delete dir="build"/>

</target>

<target name="compile" description='Generate .class files'> <mkdir dir="build/classes"/>

<javac srcdir="src" destdir="build/classes"/> </target>

<target name="jar" description='Build distributable .jar'> <mkdir dir="build/jar"/>

<jar destfile="build/jar/HelloWorld.jar" basedir="build/classes"> <manifest>

<attribute name="Main-Class" value="oata.HelloWorld"/> </manifest>

</jar> </target>

<target name="run" description='Run program' > <java jar="build/jar/HelloWorld.jar" fork="true"/> </target>

</project>

34

Check that build.xml

$ ant -projecthelp

Buildfile: build.xml Main targets:

clean Tidy up

compile Generate .class files jar Build distributable .jar run Run program

You will (probably) need to define the environment variables JAVA_HOME (directory where JDK installed), and ANT_HOME (directory where ant installed), and you will

have to modify your PATH to include the /bin directory of your ant installation. 35

Compile

<target name="compile" description='Generate .class files'>

<mkdir dir="build/classes"/>

<javac srcdir="src" destdir="build/classes"/> </target>

• Subtasks

– mkdir

• Create directory build/classes (does nothing if directory exists) • Just the one attribute – the directory name

• No nested elements

– javac

• Compile the code (implicitly all .java files in src, including packaged classes in subdirectories of src)

• Place .class files in "destdir" directory (creating package subdirectories as needed)

• javac has many possible attributes and can have nested elements (more examples later)

Compile depends="clean"? Well that would mean recompile everything each time; you could but why would you. The javac compiler can check dates on .java and .class files and only recompile things that have been changed.

(7)

clean

<target name="clean" description='Tidy up' >

<delete dir="build"/> </target>

• Delete task

– Attributes • file • dir • verbose, quiet • failonerror

– If you want to selectively delete some of files in a directory, the delete task can contain nested "fileset" elements that identify the particular files; e.g.

<delete>

<fileset dir="." includes="**/*.bak"/> </delete>

deletes all files with the extension .bak from the current directory and any

subdirectories. 37

run

<target name="run" description='Run program' > <java jar="build/jar/HelloWorld.jar" fork="true"/> </target>

• Java task

– Lots of attributes and nested elements, one important one used here is "fork"

• You can run an application in the JVM that is currently running ant! This is often problematic as if something goes amiss in your program the ant build also collapses. • Better to fork a new JVM

• (If starting client and server programs, you will need to fork separate JVMs)

38

A more refined build.xml

• The Apache example continues with

refinements;

– The first refinement relates to use of symbolic property names for things like directories used to store classes

• Using properties makes it possible to change the directory used by making a single change to a property value rather than hunting down all references to the directory

– The second refinement is the specification of dependencies –

• e.g. you can't really "run" the program until you have built the .jar file, this constraint really should be explicit in the build file

39

build.xml

<project name="HelloWorld" basedir="." default="main"> <property name="src.dir" value="src"/>

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

<property name="classes.dir" value="${build.dir}/classes"/> <property name="jar.dir" value="${build.dir}/jar"/>

<property name="main-class" value="oata.HelloWorld"/> <target name="clean">

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

40

build.xml

<project name="HelloWorld" basedir="." default="main"> …

<target name="compile"> <mkdir dir="${classes.dir}"/>

<javac srcdir="${src.dir}" destdir="${classes.dir}"/> </target>

<target name="jar" depends="compile"> <mkdir dir="${jar.dir}"/> <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}"> <manifest> <attribute name="Main-Class" value="${main-class}"/> </manifest> </jar> </target> Translation: make a directory for .class files compile all .java in “src” directory

Translation:

make a directory for distribution files create the .jar file, add all .class

files, from base directory and in .jar’s manifest file identify the main class

41

build.xml

<project name="HelloWorld" basedir="." default="main"> …

<target name="run" depends="jar">

<java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/>

</target>

<target name="clean-build" depends="clean,jar"/> <target name="main" depends="clean,run"/> </project>

Ask for target main: ant has to do "clean" first, then try "run"; and to do "run" ant must do "jar" first, which means it must start with "compile".

Translation:

You’ve got to build the .jar file before you can run it; if you have the .jar file the fork a new JDK interpreter and run the program

(8)

run

1. $ ant

2. Buildfile: build.xml 3. clean:

4. [delete] Deleting directory /home/hsimpson/tmp/build 5. compile:

6. [mkdir] Created dir: /home/hsimpson/tmp/build/classes

7. [javac] Compiling 1 source file to /home/hsimpson/tmp/build/classes 8. jar:

9. [mkdir] Created dir: /home/hsimpson/tmp/build/jar

10. [jar] Building jar: /home/hsimpson/tmp/build/jar/HelloWorld.jar 11. run:

12. [java] Hello World

13. main: 14. BUILD SUCCESSFUL 15. Total time: 6 seconds

ant with no arguments – build default target, i.e. "main" First, clean

Next, compile Now build .jar file

And run application

Output from forked JVM running application; lines get tagged with [java] as they are part of a <java > task

43

Second example

Arguments, classpaths, using

libraries

44

Application and ant use

• Simple database access

– Little “procedural” program that opens connection to database, then lists contents of a small table.

• Some extra ant features

– Interactive input of property values

• (Not always wise, means that may not be able to run inside IDE – because ant may not be able to access standard input¶)

– Library (database driver)

• Must be added to classpath for run-time

– Building a distributable

• Must add a copy of the library (cannot simply have executable .jar file; need libraries as well; and a manifest entry specifying how libraries to be added to classpath)

¶Works OK in NetBeans 45

Database table

create table teams (

Team1 varchar(32), Team2 varchar(32), Score1 number, Score2 number );

insert into teams values (‘norths’, ‘souths’, 1, 2);

46

DB1

import java.sql.*;

public class DB1 {

private static final String dbDriverName = "oracle.jdbc.driver.OracleDriver"; public static void main(String[] args) { } } 47

DB1

public static void main(String[] args) {

if(args.length!=3) {

System.out.println("Need db url, user, and password arguments"); System.exit(1);

}

String dbURL = args[0]; String user = args[1]; String pwd = args[2]; Connection dbConnection = null; try {

Class.forName(dbDriverName);

dbConnection = DriverManager.getConnection( dbURL, user, pwd); }

catch(Exception e) {

System.out.println("Failed to get a database connection"); System.out.println(e);

System.exit(1); }

Pick up command line arguments with connection information, then load database driver and establish connection 48

(9)

DB1

public static void main(String[] args) {

try {

Statement stmt = dbConnection.createStatement(); ResultSet rs = stmt.executeQuery("select * from teams"); System.out.println("Team1\tTeam2\tScore1\tScore2\t"); while(rs.next()) { System.out.println( rs.getString("TEAM1") + "\t" + rs.getString("TEAM2") + "\t" + rs.getString("SCORE1") + "\t" + rs.getString("SCORE2")); } } catch(SQLException sqle) { …} finally {

try { dbConnection.close(); } catch(Exception ignoreit) { } }

System.out.println("Listing of data table complete"); System.out.println("Program terminating normally");

} 49

build.xml

$ ant -projecthelp Buildfile: build.xml Main targets: clean Tidy up compile Compile code

dist Build a distribution directory with library inputprops Interactive prompt for username etc main Prepare and run

run Run application Default target: main

50

Build.xml

<project name="DBDemo" default="main" basedir="." > <property name="dbURL“

value="jdbc:oracle:thin:@wraith:1521:csci" /> <property name="driver" value="ojdbc14.jar" /> <property name="dbinstalldir"

value="/usr/local/instantclient_10_2/" /> <property name="dbdriverjar"

value="${dbinstalldir}${driver}" /> <property name="src.dir" value="src"/> <property name="build.dir" value="build"/>

<property name="dist.dir" value ="dist" /> <property name="lib.dir" value="${dist.dir}/lib" /> <property name="classes.dir“

value="${build.dir}/classes"/> <property name="main-class" value="DB1"/>

Translation: “Properties” (environment

variables) defining things like the URL for the database, the location and file name for the db-driver, and names for directories associated with project

51

Properties

• Can build up properties

– Here need to specify driver .jar file

– And its location

– Values could change independently

<property name="driver" value="ojdbc14.jar" /> <property name="dbinstalldir" value="/usr/local/instantclient_10_2/" /> <property name="dbdriverjar" value="${dbinstalldir}${driver}" /> 52

Build.xml

<target name="clean" description="Tidy up" >

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

<target name="compile" description="Compile code" > <mkdir dir="${classes.dir}"/>

<javac srcdir="${src.dir}" destdir="${classes.dir}"/> </target>

<target name="main" depends="clean,run" description="Prepare and run" />

Translation: should be obvious!

53

Build.xml

<target name="run" depends="compile, inputprops" description="Run application">

<echo message="Starting application, will connect to ${dbURL}" /> <echo message="for user ${dbUser}" />

<java classname="${main-class}"fork="true">

<arg value="${dbURL}" /> <arg value="${dbUser}" /> <arg value="${dbPWD}" /> <classpath> <pathelement location="${classes.dir}" /> <pathelement location="${dbdriverjar}" /> </classpath> </java>

<echo message="Run completing" /> </target>

Translation:

defining command line arguments for newly forked process and setting the “classpath” so JRE can find the classes that must be loaded

(10)

run

• Here running the specified main class from the class files in the build directory

• But also need the database driver in the classpath • So have an explicit <classpath> subelement that lists the

various directories that should be searched for class loading

<java classname="${main-class}"fork="true">

… <classpath> <pathelement location="${classes.dir}" /> <pathelement location="${dbdriverjar}" /> </classpath> </java> 55

arguments

• Command line arguments

that are to be

passed to the application appear in <arg>

subelements

<java classname="${main-class}"fork="true">

<arg value="${dbURL}" /> <arg value="${dbUser}" /> <arg value="${dbPWD}" /> <classpath> … </classpath> </java>

Later will see example where pass arguments to JVM 56

Arguments

• (Logically, should have had 4 arguments

– Class used for database driver – URL of database

– User name – Password

– here, class is actually defined by String in program).

• URL defined as property in build.xml

• Not too desirable to have user-name and

database password left around in build.xml file!

So, ask for them when needed

57

Arguments

<project name="DBDemo" default="main" basedir="." > <property name="dbURL"

value="jdbc:oracle:thin:@wraith:1521:csci" /> <target name="inputprops" description=

"Interactive prompt for username etc" > <input message="User name : "

addproperty="dbUser“ defaultvalue="HSimpson" /> <input message="Password : " addproperty="dbPWD" /> </target> 58

<input> task

• Attributes include

– Prompt for user

– Name of property to be added (you cannot

change a property set by a <property> tab)

– Optional default

– If the input is essentially an enumerated type

with only certain permitted values, it is

possible to add a check for these.

59

No <input>

• It is possible to supply property values on

the command line when starting ant

ant –Duser=homer –Dpassword=donut main

• However, unless the script is something

that you use very often, the prompting via

the <input> task is helpful.

(11)

$ ant main Buildfile: build.xml clean:

[delete] Deleting directory /home/hsimpsons/Ex1/build [delete] Deleting directory /home/hsimpsons/Ex1/dist compile:

[mkdir] Created dir: /home/hsimpsons/Ex1/build/classes [javac] Compiling 1 source file to /home/hsimpsons/Ex1/build/classes inputprops:

[input] User name : homer

[input] Password : doh

run:

[echo] Starting application, will connect to jdbc:oracle:thin:@wraith:1521:csci [echo] for user homer

[java] Team1 Team2 Score1 Score2 [java] norths souths 2 0 [java] Easts Wests 3 2 [java] City Country 2 2 [java] River Forest 0 0 [java] Listing of data table complete [java] Program terminating normally [echo] Run completing main:

BUILD SUCCESSFUL Total time: 9 seconds

61

Distributable version

• Need something more elaborate

– Distribution directory

• .jar file with classes defined for this application • lib subdirectory

– Copies of .jar files for all libraries

– .jar file needs manifest containing

• Name of main class • Classpath specification

• Run by “cd dist; java –jar DBDemo.jar …”

62

build.xml

<target name="dist" depends="compile“

description="Build a distribution directory with library" > <mkdir dir="${dist.dir}" />

<mkdir dir="${lib.dir}" />

<copy file="${dbdriverjar}" todir="${lib.dir}" /> <jar destfile="${dist.dir}/${ant.project.name}.jar" basedir="${classes.dir}"> <manifest> <attribute name="Main-Class" value="${main-class}"/> <attribute name="Class-Path" value="lib/${driver}" /> </manifest> </jar> </target> 63

And run

$ cd dist

$ java -jar DBDemo.jar \

jdbc:oracle:thin:@wraith:1521:csci homer doh

Team1 Team2 Score1 Score2

norths souths 2 0

Easts Wests 3 2

City Country 2 2

River Forest 0 0

Listing of data table complete

Program terminating normally

Here entering run command at prompt, so can simply enter the command line argument with dbURL, name, pwd

64

Third example

Parallel sequential tasks

65

RMI example

• This example illustrates test deployment of

an RMI client server application using

Java 1.4 conventions.

• Java 1.5 simplifies things a little by eliminating the need for specially generated client stubs (using

java.lang.reflect instead on both client and server) and also eliminating the need for a HTTP based class file server!

(12)

Java RMI (1.4)

Client computer Server host computer

Client application Server application rmiregistry Server object registers Server object 67

Java RMI

Client computer Server host computer

Client application Server application rmiregistry Server object registers Naming.lookup() Server object 68

Java RMI

Client computer Server host computer

Client application Server application Web Server rmiregistry Server object registers http class load requests Server object Collection of stub classes 69

Java RMI

Client computer Server host computer

Client application Server application Web Server rmiregistry Server object stub Invoke operation 70

Actual application

• Server process hosting principal server object – a

"factory"

• Clients lookup this factory via rmiregistry and connect, using "factory" object to create a private "session" object • Clients use "session" object;

– after client disconnects, Java rmi distributed garbage collection system will reclaim discarded session

• CalculatorFactory(factory object)

– Makes Calculator objects

• Calculator(session object)

– Simple 4-function integer calculator

71

Server-host Client1-host

Client2-host

rmiregistry - the factory is here

Client application Client application Server process CalculatorFactory Calculator1 Calculator2 network 72

(13)

Starting processes

• One part of this example illustrates how

you could set those processes running

– rmiregistry process

– “classfileserver” process

• You didn’t have to run a full HTTP server like Apache

• For test purposes, there was a little HTTP server supplied by Sun – very limited functionality!

– Server process

– Client process

73

Distribution directories

• Another aspect of RMI deployment (1.4

style) was to have separate directories of

.class files

– clientdir : collection of files that had to be

copied to client machine (main client program

etc)

– serverdir: collection of files used by server

– deploydir: collection of files made available for

download from the HTTP server (client stub,

things like application defined exceptions)

74

rmic

• You also had to generate the client stub

code

– rmic took the definition of the actual

implementation class for the server (not the

interface) and generated the stub from this

– The rmic compilation step had to be fitted into

the compile chain at the appropriate point

75

Getting a bit complex

• So, a more complex build.xml

– Lots of properties defining subdirectories etc (actually, it just assumes that the classfileserver is located in a related directory, doesn’t properly specify its location)

– Elaborate compile sequence with javac compile steps followed by rmic steps

– Parallel/Sequential task for starting the processes in the appropriate order (with time delays as needed so they are ready before you request actions!)

• And some simplifications;

– apart from classfileserver setup being simplified, all the classes were defined in the default package!

– RMI programs require security policy files, the same simplified one was used here for both client and server

76

Build.xml

$ ant -projecthelp Buildfile: build.xml Main targets:

build Compile and stub generate clean Tidy up

deploy Place .class files in directories run Start rmiregistry, class file

server, server, then client Default target: build

77

build.xml

<project name="rmi-conventional" default="build" basedir=".">

<!--APORT and BPORT - non-standard ports used for a test rmiregistry and class file server

-->

<property name="APORT" value="13456" /> <property name="BPORT" value="14567" />

(14)

build.xml

<project name="rmi-conventional" default="build" basedir=".">

<!-- directories, note assumption about availability of standard ClassFileServer in related directory --> <property name="build" location="./build" /> <property name="src" location="." />

<property name="clientdir" location="./clientdir" /> <property name="serverdir" location="./serverdir" /> <property name="deploydir" location="./deploydir" /> <property name="classfileserver“

location="../../ClassFileServer" />

All the source files were in the same directory as the build.xml

The .class files are generated in the ./build subdirectory, then appropriate subsets are copied to other directories79

build.xml

<project name="rmi-conventional" default="build" basedir=".">

<target name="clean" description="Tidy up" > <delete dir="${build}"/>

<delete dir="${clientdir}"/> <delete dir="${serverdir}"/> <delete dir="${deploydir}"/> </target>

<target name="init" > <mkdir dir="${build}" /> </target>

80

build.xml

<target name="build" depends="init“

description="Compile and stub generate" > <javac srcdir="${src}" destdir="${build}">

<include name="**"/> </javac>

<rmic base="${build}" classname="CalculatorImpl" /> <rmic base="${build}“

classname="CalculatorFactoryImpl" /> </target>

Compile code, then use rmic to generate clientstub classes for the two server implementation classes used in the example

81

build.xml : deploy

<target name="deploy" depends="build“

description="Place .class files in directories" > <echo message=

"Creating deployment directories and copying files" /> <mkdir dir="${clientdir}"/> <mkdir dir="${serverdir}"/> <mkdir dir="${deploydir}"/> <!-- Client --> <copy file="${build}/CalculatorClient.class" todir="${clientdir}" /> <copy file="${build}/Calculator.class“ todir="${clientdir}" /> <copy file="${build}/CalculatorFactory.class“ todir="${clientdir}" />

<copy file="policyfile" todir="${clientdir}" />

Copy files to separate directories 82

build.xml : deploy

<target name="deploy" depends="build“

description="Place .class files in directories" > <!-- Deploy --> <copy file="${build}/Calculator.class“ todir="${deploydir}" /> <!-- Server --> <copy file="${build}/Calculator.class“ todir="${serverdir}" /> </target> 83

Run task

• The build.xml has a run task that starts

separate processes for class-file-server,

rmiregistry, server, and client. All run on

the local machine.

– The rmiregistry is started first and given time

to open its port and initialize

– The class file server is then started – it has to

be given a reference

(15)

Run task – parallel activities

<target name="run" depends="deploy“

description="Start rmiregistry, class file server, server, then client" >

<parallel>

<sequential>

<echo message="Hopefully start rmiregistry" />

</sequential> <sequential>

<echo message="Hopefully start classfileserver" />

</sequential> <sequential>

<sleep seconds="15" />

<echo message="Should start server and let it register" />

</sequential> <sequential>

<sleep seconds="20" />

<echo message="Should start client and let it contact server" />

</sequential> </parallel> </target> 85

Rmiregistry task

<parallel> <sequential>

<echo message="Hopefully start rmiregistry" /> <exec executable="rmiregistry" >

<arg value="${APORT}" /> </exec>

</sequential>

Task: print message, then launch rmiregistry (has to be on your PATH, it should be as in same directory as java and javac); argument is port that registry is to use (don’t run at default port – that is for production programs not tests).

86

Class file server task

<parallel>

<sequential>

<echo message="Hopefully start classfileserver" /> <java fork="true" failonerror="true“

classname="ClassFileServer" > <arg line="${BPORT} ${deploydir}/" /> <classpath>

<pathelement location="${classfileserver}"/> </classpath>

</java> </sequential>

Start the class file server (pathelement identifies directory with its .class files); class file server accepts HTTP requests at port ${BPORT}; class file server has to be given directory where downloadable client stub .class files are

held (deploydir). 87

Server task

• Server

– Wait a little to let rmiregistry and class file

server to start up

– Execute server code with java in new JVM

• Jvmarg – argument for JVM

– URL of class file server – Security policy file

• Classpath

– Location of directory with the server files

88

Server task

<parallel> <sequential> <sleep seconds="15" />

<echo message="Should start server and let it register" /> <java fork="true" failonerror="true“

classname="Server">

<arg line="localhost ${APORT}" /> <jvmarg value=

"Djava.rmi.server.codebase=http://localhost:${BPORT}/" /> <jvmarg value="-Djava.security.policy=policyfile" /> <classpath> <pathelement location="${serverdir}"/> </classpath> </java> </sequential> 89

Client task

<parallel> <sequential> <sleep seconds="20" />

<echo message="Should start client and let it contact server" />

<java fork="true" failonerror="true" classname="CalculatorClient"> <arg line="localhost ${APORT}" />

<jvmarg value="-Djava.security.policy=policyfile" /> <classpath> <pathelement location="${clientdir}"/> </classpath> </java> </sequential> </parallel> 90

(16)

Input to programs launched from ant

• Can have input to Java program launched

in ant:

– Mix of input and output from program and ant

is a bit confusing;

the output all gets tagged with [java] task

identifier (which will usually disrupt intended

layout);

(also when prompting for input you need to

use println() – if you just print() then the

prompt for your input doesn’t appear, the

program simply waits)

91

Input

• If the application can take input from a file,

you can add an input attribute to the <java

..> task that identifies the file.

• Otherwise – make your application use a

GUI to get its input and display its ouput!

• Or – use ant to build .jar and then run at

command prompt level

References

Related documents

If a consumer cannot solve the dispute arising from an online sales or service contract directly with the trader, the dispute still can be solved through the platform with

The paper is therefore, out to examine the impact of the foreign exchange market on the economic growth of Nigeria between 1996 to 2005 by considering the rate at

Kalandoor Career DMCC Careers Dubai Customs DP World Career Dalkia Dubai Career ADGAS Career Mattex Career [email protected]. Paris Gallery

My duties included policy development, the design, implementation and monitoring of numerous action research projects, the development of original training resources (see

We also tried the ratio of pension assets to firm assets to capture how big the plan is relative to the firm. The notion was that if the plan is large relative to the firm,

Lebedev Physical Institute, Moscow, Russia 43: Also at California Institute of Technology, Pasadena, USA 44: Also at Budker Institute of Nuclear Physics, Novosibirsk, Russia 45: Also

The radiography control button was released before the exposure end. The display indicates the remaining exposure time. Based on this time, you must decide whether to develop

Evaluation of soil chemical fertility in representative farmers’ fields in the Indian state of Karnataka revealed the occurrence of widespread deficiency of plant nutrients such as