line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
########################################################################### |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# Java::SJ |
4
|
|
|
|
|
|
|
# |
5
|
|
|
|
|
|
|
# $Id: SJ.pm,v 1.4 2003/07/20 18:52:15 wiggly Exp $ |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# $Author: wiggly $ |
8
|
|
|
|
|
|
|
# |
9
|
|
|
|
|
|
|
# $DateTime$ |
10
|
|
|
|
|
|
|
# |
11
|
|
|
|
|
|
|
# $Revision: 1.4 $ |
12
|
|
|
|
|
|
|
# |
13
|
|
|
|
|
|
|
########################################################################### |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
package Java::SJ; |
16
|
|
|
|
|
|
|
|
17
|
1
|
|
|
1
|
|
18096
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
34
|
|
18
|
|
|
|
|
|
|
|
19
|
1
|
|
|
1
|
|
5
|
use Carp; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
83
|
|
20
|
1
|
|
|
1
|
|
7
|
use Cwd; |
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
72
|
|
21
|
1
|
|
|
1
|
|
2717
|
use Data::Dumper; |
|
1
|
|
|
|
|
15821
|
|
|
1
|
|
|
|
|
209
|
|
22
|
1
|
|
|
1
|
|
1351
|
use English; |
|
1
|
|
|
|
|
5805
|
|
|
1
|
|
|
|
|
8
|
|
23
|
1
|
|
|
1
|
|
671
|
use File::Path; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
72
|
|
24
|
1
|
|
|
1
|
|
1187
|
use File::Slurp; |
|
1
|
|
|
|
|
17021
|
|
|
1
|
|
|
|
|
91
|
|
25
|
1
|
|
|
1
|
|
13
|
use File::Spec; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
25
|
|
26
|
1
|
|
|
1
|
|
1439
|
use File::Temp qw( tempfile ); |
|
1
|
|
|
|
|
24312
|
|
|
1
|
|
|
|
|
80
|
|
27
|
1
|
|
|
1
|
|
5843
|
use IO::File; |
|
1
|
|
|
|
|
3068
|
|
|
1
|
|
|
|
|
288
|
|
28
|
1
|
|
|
1
|
|
15
|
use IO::Handle; |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
72
|
|
29
|
1
|
|
|
1
|
|
1312
|
use Java::SJ::Config; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
our $VERSION = '0.01'; |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
our $LOG = undef; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
########################################################################### |
36
|
|
|
|
|
|
|
# |
37
|
|
|
|
|
|
|
# sj - main program for sj script |
38
|
|
|
|
|
|
|
# |
39
|
|
|
|
|
|
|
########################################################################### |
40
|
|
|
|
|
|
|
sub sj |
41
|
|
|
|
|
|
|
{ |
42
|
|
|
|
|
|
|
my $config = new Java::SJ::Config; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
my $script = shift @ARGV; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
my $log_file; |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
my $handle; |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
croak "[ERROR] Please specify a script file on the command line.\n" |
51
|
|
|
|
|
|
|
unless defined( $script ); |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# find out the canonical path to the script |
54
|
|
|
|
|
|
|
$script = File::Spec->rel2abs( $script ); |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# open the script and read it into our configuration |
57
|
|
|
|
|
|
|
$handle = new IO::File( "<$script" ) |
58
|
|
|
|
|
|
|
or croak "[ERROR] Cannot open file $script, $!\n"; |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
$config->load_app_configuration( $handle, 0 ) |
61
|
|
|
|
|
|
|
or croak "[ERROR] Could not load configuration\n"; |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
$handle->close; |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
# open LOG filehandle |
66
|
|
|
|
|
|
|
$log_file = $config->get_var( 'dir.log' ) . "/sj.log"; |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
$LOG = new IO::File $log_file, "w" |
69
|
|
|
|
|
|
|
or croak "[ERROR] Cannot open log file $log_file, $!\n"; |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
print $LOG "[INFO] Java::SJ::sj\n"; |
72
|
|
|
|
|
|
|
print $LOG "[INFO] PROGRAM $PROGRAM_NAME\n"; |
73
|
|
|
|
|
|
|
print $LOG "[INFO] PID $PROCESS_ID\n"; |
74
|
|
|
|
|
|
|
print $LOG "[INFO] CWD " . getcwd . "\n"; |
75
|
|
|
|
|
|
|
print $LOG "[INFO] ARGV " . join( ' ', @ARGV ) . "\n"; |
76
|
|
|
|
|
|
|
print $LOG "[INFO] SCRIPT " . $script . "\n"; |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
print $LOG "[DEBUG] configuration\n"; |
80
|
|
|
|
|
|
|
print $LOG "[DEBUG]\n"; |
81
|
|
|
|
|
|
|
print $LOG Dumper( $config ); |
82
|
|
|
|
|
|
|
print $LOG "\n\n"; |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
print $LOG "[INFO] Now generate a cached script file in our script dir.\n"; |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
my $program_file = $config->get_var( 'dir.script' ) . "/" . $config->get_var( 'app.name' ); |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
print $LOG "[INFO] Program file : $program_file\n"; |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# ensure script directory exists |
92
|
|
|
|
|
|
|
my ( $volume, $directories, $file ) = File::Spec->splitpath( $program_file ); |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
eval |
95
|
|
|
|
|
|
|
{ |
96
|
|
|
|
|
|
|
mkpath( $directories ); |
97
|
|
|
|
|
|
|
}; |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
if( $@ ) |
100
|
|
|
|
|
|
|
{ |
101
|
|
|
|
|
|
|
( $handle, $program_file ) = tempfile( 'sj_script.XXXXXXXX', DIR => $config->get_var( 'dir.tmp' ) ); |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
else |
104
|
|
|
|
|
|
|
{ |
105
|
|
|
|
|
|
|
$handle = new IO::File( ">$program_file" ) |
106
|
|
|
|
|
|
|
or croak "[ERROR] Cannot open program file $program_file for writing, $!\n"; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
print $handle "#!$EXECUTABLE_NAME\n"; |
110
|
|
|
|
|
|
|
print $handle "use Java::SJ;\n"; |
111
|
|
|
|
|
|
|
print $handle "&Java::SJ::run;\n"; |
112
|
|
|
|
|
|
|
print $handle "__END__\n"; |
113
|
|
|
|
|
|
|
print $handle read_file( $script ); |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
$handle->close; |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# make it executable |
118
|
|
|
|
|
|
|
chmod 0755, $program_file; |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
# execute the script |
121
|
|
|
|
|
|
|
{ |
122
|
|
|
|
|
|
|
exec ( $program_file, @ARGV ); |
123
|
|
|
|
|
|
|
}; |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
croak "[ERROR] Could not exec program $program_file, $!\n"; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
########################################################################### |
130
|
|
|
|
|
|
|
# |
131
|
|
|
|
|
|
|
# run |
132
|
|
|
|
|
|
|
# |
133
|
|
|
|
|
|
|
########################################################################### |
134
|
|
|
|
|
|
|
sub run |
135
|
|
|
|
|
|
|
{ |
136
|
|
|
|
|
|
|
my $config = new Java::SJ::Config; |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
my $vm = undef; |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
my @prop = (); |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
my @param = (); |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
my @cp = (); |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
my $command = ''; |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
my $log_file; |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
my ( $key, $bcp, $pbcp, $abcp, $cp ); |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
$config->load_script_configuration; |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# open LOG filehandle |
155
|
|
|
|
|
|
|
$log_file = $config->get_var( 'dir.log' ) . "/sj.log"; |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
$LOG = new IO::File $log_file, "w" |
158
|
|
|
|
|
|
|
or croak "[ERROR] Cannot open log file $log_file, $!\n"; |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
print $LOG "[INFO] Java::SJ::run\n"; |
161
|
|
|
|
|
|
|
print $LOG "[INFO] PROGRAM $PROGRAM_NAME\n"; |
162
|
|
|
|
|
|
|
print $LOG "[INFO] PID $PROCESS_ID\n"; |
163
|
|
|
|
|
|
|
print $LOG "[INFO] CWD " . cwd . "\n"; |
164
|
|
|
|
|
|
|
print $LOG "[DEBUG] configuration\n"; |
165
|
|
|
|
|
|
|
print $LOG "[DEBUG]\n"; |
166
|
|
|
|
|
|
|
print $LOG Dumper( $config ); |
167
|
|
|
|
|
|
|
print $LOG "\n\n"; |
168
|
|
|
|
|
|
|
print $LOG "[DEBUG] BOOTCLASSPATH : " . $config->{'bootclasspath'}->generate_classpath( $config->get_var( 'dir.lib' ) ) . "\n"; |
169
|
|
|
|
|
|
|
print $LOG "[DEBUG] PBOOTCLASSPATH : " . $config->{'prepend_bootclasspath'}->generate_classpath( $config->get_var( 'dir.lib' ) ) . "\n"; |
170
|
|
|
|
|
|
|
print $LOG "[DEBUG] ABOOTCLASSPATH : " . $config->{'append_bootclasspath'}->generate_classpath( $config->get_var( 'dir.lib' ) ) . "\n"; |
171
|
|
|
|
|
|
|
print $LOG "[DEBUG] CLASSPATH : " . $config->{'classpath'}->generate_classpath( $config->get_var( 'dir.lib' ) ) . "\n"; |
172
|
|
|
|
|
|
|
print $LOG "\n\n"; |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
print $LOG "[DEBUG] get vm we need to use\n"; |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
$vm = $config->{'vm'}{$config->{'vmref'}}; |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
print $LOG "[DEBUG] got VM '" . $vm->name . "'\n"; |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
print $LOG "[DEBUG] construct environment\n"; |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
foreach $key ( keys %{$config->{'env'}} ) |
184
|
|
|
|
|
|
|
{ |
185
|
|
|
|
|
|
|
print $LOG "[DEBUG] ENV $key -> " . $config->{'env'}{$key} . "\n"; |
186
|
|
|
|
|
|
|
$ENV{$key} = $config->{'env'}{$key}; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
foreach $key ( keys %{$vm->{'env'}} ) |
190
|
|
|
|
|
|
|
{ |
191
|
|
|
|
|
|
|
print $LOG "[DEBUG] ENV $key -> " . $vm->{'env'}{$key} . "\n"; |
192
|
|
|
|
|
|
|
$ENV{$key} = $vm->{'env'}{$key}; |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
# set JAVA_HOME based on VM |
196
|
|
|
|
|
|
|
$ENV{'JAVA_HOME'} = $vm->home; |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
print $LOG "[DEBUG] construct property list\n"; |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
foreach $key ( keys %{$config->{'prop'}} ) |
201
|
|
|
|
|
|
|
{ |
202
|
|
|
|
|
|
|
print $LOG "[DEBUG] PROP $key -> " . $config->{'prop'}{$key} . "\n"; |
203
|
|
|
|
|
|
|
push @prop, sprintf( "-D%s=%s", $key, $config->{'prop'}{$key} ); |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
foreach $key ( keys %{$vm->{'prop'}} ) |
207
|
|
|
|
|
|
|
{ |
208
|
|
|
|
|
|
|
print $LOG "[DEBUG] PROP $key -> " . $vm->{'prop'}{$key} . "\n"; |
209
|
|
|
|
|
|
|
push @prop, sprintf( "-D%s=%s", $key, $vm->{'prop'}{$key} ); |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
print $LOG "[DEBUG] property list : " . join( ' ', @prop ) . "\n"; |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
print $LOG "[DEBUG] construct parameter list\n"; |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
foreach $key ( keys %{$config->{'param'}} ) |
217
|
|
|
|
|
|
|
{ |
218
|
|
|
|
|
|
|
print $LOG "[DEBUG] PARAM $key -> " . $config->{'param'}{$key} . "\n"; |
219
|
|
|
|
|
|
|
push @param, sprintf( "%s%s", $key, $config->{'param'}{$key} ); |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
foreach $key ( keys %{$vm->{'param'}} ) |
223
|
|
|
|
|
|
|
{ |
224
|
|
|
|
|
|
|
print $LOG "[DEBUG] PARAM $key -> " . $vm->{'param'}{$key} . "\n"; |
225
|
|
|
|
|
|
|
push @param, sprintf( "%s%s", $key, $vm->{'param'}{$key} ); |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
print $LOG "[DEBUG] param list : " . join( ' ', ( @param, @ARGV ) ) . "\n"; |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
print $LOG "[DEBUG] construct java command line\n"; |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
$bcp = $config->{'bootclasspath'}->generate_classpath( $config->get_var( 'dir.lib' ) ); |
234
|
|
|
|
|
|
|
$pbcp = $config->{'prepend_bootclasspath'}->generate_classpath( $config->get_var( 'dir.lib' ) ); |
235
|
|
|
|
|
|
|
$abcp = $config->{'append_bootclasspath'}->generate_classpath( $config->get_var( 'dir.lib' ) ); |
236
|
|
|
|
|
|
|
$cp = $config->{'classpath'}->generate_classpath( $config->get_var( 'dir.lib' ) ); |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
if( length( $bcp ) ) |
239
|
|
|
|
|
|
|
{ |
240
|
|
|
|
|
|
|
push @cp, "-Xbootclasspath:$bcp"; |
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
if( length( $pbcp ) ) |
244
|
|
|
|
|
|
|
{ |
245
|
|
|
|
|
|
|
push @cp, "-Xbootclasspath/p:$pbcp"; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
if( length( $abcp ) ) |
249
|
|
|
|
|
|
|
{ |
250
|
|
|
|
|
|
|
push @cp, "-Xbootclasspath/a:$abcp"; |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
if( length( $cp ) ) |
254
|
|
|
|
|
|
|
{ |
255
|
|
|
|
|
|
|
push @cp, "-classpath $cp"; |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
#$command .= 'echo "'; |
259
|
|
|
|
|
|
|
$command .= $vm->home; |
260
|
|
|
|
|
|
|
$command .= '/bin/java'; |
261
|
|
|
|
|
|
|
$command .= ' '; |
262
|
|
|
|
|
|
|
$command .= join( ' ', @cp ); |
263
|
|
|
|
|
|
|
$command .= ' '; |
264
|
|
|
|
|
|
|
$command .= join( ' ', @prop ); |
265
|
|
|
|
|
|
|
$command .= ' '; |
266
|
|
|
|
|
|
|
$command .= $config->get_var( 'app.class' ); |
267
|
|
|
|
|
|
|
$command .= ' '; |
268
|
|
|
|
|
|
|
$command .= join( ' ', @param ); |
269
|
|
|
|
|
|
|
$command .= ' '; |
270
|
|
|
|
|
|
|
$command .= join( ' ', @ARGV ); |
271
|
|
|
|
|
|
|
$command .= ' '; |
272
|
|
|
|
|
|
|
#$command .= '"'; |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
print $LOG "[DEBUG] write out PID file if required\n"; |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
print $LOG "[DEBUG] command :\n$command\n\n"; |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
# execute java |
279
|
|
|
|
|
|
|
exec $command; |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
########################################################################### |
283
|
|
|
|
|
|
|
1; |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=pod |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=head1 NAME |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
Java::SJ - Highly configurable Java program startup system |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
=head1 SYNOPSIS |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
sj myprogram.sj |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=head1 DESCRIPTION |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
This module allows you to very easily run Java services that rely on complex |
298
|
|
|
|
|
|
|
configuration at the VM and library level. It also provides an easy way of |
299
|
|
|
|
|
|
|
specifying a sensible 'default' configuration that can be overridden by specific |
300
|
|
|
|
|
|
|
applications should they need to. |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
The system is configured on a machine and application level. The system |
303
|
|
|
|
|
|
|
looks for configuration files in a set of well-known locations, currently |
304
|
|
|
|
|
|
|
these are: |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=over 4 |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
=item * F |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=item * F<.sj.conf> in users HOME directory |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=item * F<.sj.conf> in current working directory |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=back |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
Every application is defined in terms of a similar configuration file. The |
317
|
|
|
|
|
|
|
configuration system has been designed so that it is easy to write a simple |
318
|
|
|
|
|
|
|
and minimal configuration file for a program. |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
Provided the system has a fairly complete configuration associated with it |
321
|
|
|
|
|
|
|
then an application configuration file need only have the class name to be |
322
|
|
|
|
|
|
|
executed. |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=head1 FEATURES |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
Some of the Goodness(tm) that you get with SJ is as follows: |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=over 4 |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=item Easy co-existence of multiple Virtual Machines |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
Any number of VMs can be supported and used concurrently on the same |
333
|
|
|
|
|
|
|
machine. Developers don't need to know where the JDK/JRE resides, just a |
334
|
|
|
|
|
|
|
symbolic name for it. |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
=item Easy co-existence of multiple versions of JAR files |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
Any number of different versions of the same JAR file may co-exist. SJ sorts |
339
|
|
|
|
|
|
|
out which ones to use and only places those JAR files that are required in |
340
|
|
|
|
|
|
|
an application's CLASSPATH |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
=item Control over BOOTCLASSPATH variables |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
All three flavours of the bootclasspath can be configured on a system-wide |
345
|
|
|
|
|
|
|
and application specific basis. |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
=item Process control |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
PID files can be automatically generated and placed wherever you wish. |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
=item Cache of executable scripts |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
Application configuration files are cached as executable scripts that can be |
354
|
|
|
|
|
|
|
directly invoked. |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
=back |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
This will probably make more sense as a set of examples, so here goes. |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=head1 EXAMPLES |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
=head2 Simple Configuration |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
home="/usr/local/IBMJava-1.3.1" |
370
|
|
|
|
|
|
|
default="true"/> |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
The above minimal system configuration simply tells the system where to find |
374
|
|
|
|
|
|
|
a virtual machine called 'ibm' and that it should be used as the default VM |
375
|
|
|
|
|
|
|
unless an application specifically requests another one. |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
myclass |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
The above minimal application configuration simply provides a class file |
384
|
|
|
|
|
|
|
name to run. If both of the above simple configuration files were used then |
385
|
|
|
|
|
|
|
the class 'myclass' would have to be in the system's CLASSPATH environment |
386
|
|
|
|
|
|
|
variable already. |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
=head2 Useful Configuration |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
The above simple configuration is only really useful to test that the system |
391
|
|
|
|
|
|
|
is working. Running a simple class on the command line isn't normally very |
392
|
|
|
|
|
|
|
difficult and so sj doesn't actually add very much to the above case. |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
If we had a system where we wished to test that the same code was compatible |
395
|
|
|
|
|
|
|
with multiple virtual machines and multiple library versions then the |
396
|
|
|
|
|
|
|
following configuration files would enable us to run these programs with |
397
|
|
|
|
|
|
|
different parameters easily. |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
vendor="IBM" |
422
|
|
|
|
|
|
|
version="1.1.8" |
423
|
|
|
|
|
|
|
home="/usr/local/IBMJava-1.1.8"/> |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
vendor="IBM" |
427
|
|
|
|
|
|
|
version="1.4.1" |
428
|
|
|
|
|
|
|
home="/usr/local/IBMJava-1.4.1"/> |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
vendor="Blackdown" |
432
|
|
|
|
|
|
|
version="1.1.8" |
433
|
|
|
|
|
|
|
home="/usr/local/blackdown-1_1_8"/> |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
vendor="Sun Microsystems" |
437
|
|
|
|
|
|
|
version="1.3.1" |
438
|
|
|
|
|
|
|
home="/usr/local/sunjdk_131" |
439
|
|
|
|
|
|
|
default="true"/> |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
The above system configuration contains a lot more information than our |
444
|
|
|
|
|
|
|
initial simple example. |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
=over 4 |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
=item Variables |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
There are explicitly declared variables that SJ will use when figuring |
451
|
|
|
|
|
|
|
out where things should be read from/written to. |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
Variables may be defined in terms of other variables, even if they have not |
454
|
|
|
|
|
|
|
been declared yet. The syntax for referring to variables thorughout is the |
455
|
|
|
|
|
|
|
same as Ant, ${variable_name}. |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
=item PID file |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
It states that by default a PID file should be written when running an |
460
|
|
|
|
|
|
|
application. This is most useful for multithreaded server applications where |
461
|
|
|
|
|
|
|
you want to be able to kill or HUP the server without figuring out what the |
462
|
|
|
|
|
|
|
lead process PID is. |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=item Classpath |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
The classpath definition instructs SJ to look for the latest available |
467
|
|
|
|
|
|
|
versions of xalan, xerces and xml-apis and version 1.0.3 of the commons-cli |
468
|
|
|
|
|
|
|
libraries and add these to the classpath when running any program. |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
SJ will look for the libraries in the path defined by ${dir.lib}. |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
SJ is currently very simplistic about library versioning. If it needs to |
473
|
|
|
|
|
|
|
look for a specific version of a library then it simply looks for the |
474
|
|
|
|
|
|
|
library name and library version number joined by a single hyphen. So in the |
475
|
|
|
|
|
|
|
case of the commons-cli library SJ would look for commons-cli-1.0.3.jar in |
476
|
|
|
|
|
|
|
the ${dir.lib} directory. |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
You may be wondering how SJ figures out which is the 'latest' version of a |
479
|
|
|
|
|
|
|
JAR file if no version is specified. Quite simply it chooses the one whose |
480
|
|
|
|
|
|
|
filename begins with the required name and is lexicographically last in an |
481
|
|
|
|
|
|
|
ordered list of those filenames that match. It's not great but with any |
482
|
|
|
|
|
|
|
half-sensible version numbering scheme it will work. |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
=item Virtual Machines |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
There are four virtual machines defined here. In addition to the home |
487
|
|
|
|
|
|
|
directory for each there is now information regarding the vendor and |
488
|
|
|
|
|
|
|
version. Currently this is for informational purposes only but future |
489
|
|
|
|
|
|
|
versions of SJ should be able to choose a VM based on the version or vendor. |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
=back |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
myclass |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
myclass |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
myclass |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
The above application configurations are exactly the same as the simple |
515
|
|
|
|
|
|
|
version with the addition of a vm reference tag to determine which VM they |
516
|
|
|
|
|
|
|
should be executed under. |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
=head2 High Granularity |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
In addition to being able to specify which VMs and libraries to use you have |
521
|
|
|
|
|
|
|
complete control over the environment that the VM is run under, the |
522
|
|
|
|
|
|
|
properties that are passed the the VM and even default command line options |
523
|
|
|
|
|
|
|
on a per system, VM and application basis. |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
vendor="IBM" |
560
|
|
|
|
|
|
|
version="1.1.8" |
561
|
|
|
|
|
|
|
home="/usr/local/IBMJava-1.1.8"> |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
vendor="IBM" |
568
|
|
|
|
|
|
|
version="1.4.1" |
569
|
|
|
|
|
|
|
home="/usr/local/IBMJava-1.4.1"/> |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
vendor="Blackdown" |
573
|
|
|
|
|
|
|
version="1.1.8" |
574
|
|
|
|
|
|
|
home="/usr/local/blackdown-1_1_8"> |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
vendor="Sun Microsystems" |
581
|
|
|
|
|
|
|
version="1.3.1" |
582
|
|
|
|
|
|
|
home="/usr/local/sunjdk_131" |
583
|
|
|
|
|
|
|
default="true"/> |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
The above system configuration is identical to our useful configuration |
587
|
|
|
|
|
|
|
except we have now added directives that SJ will use to alter the |
588
|
|
|
|
|
|
|
environment and command line parameters passed to the application and VMs. |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
Using VM specific parameters you can make sure that the correct threading |
591
|
|
|
|
|
|
|
models are used or that memory limuts are enforced unless someone needs to |
592
|
|
|
|
|
|
|
tweak the settings. |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
In an application configuration file it is possible to override previously |
595
|
|
|
|
|
|
|
declared parameters such as the -Xmx directive above for the blackdown VM. |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
For example: |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
myclass |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
The L documentation describes every configuration |
609
|
|
|
|
|
|
|
directive in detail, also have a look in the sample directory for ideas. |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
=head1 TODO |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
Test, test, test. |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
=head1 BUGS |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
None known so far. Please report any and all to Nigel Rantor > |
618
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
=head1 SUPPORT / WARRANTY |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
This module is free software. IT COMES WITHOUT WARRANTY OF ANY KIND. |
622
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
=head1 LICENSE |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
The Java::SJ module is Copyright (c) 2003 Nigel Rantor. England. All rights |
626
|
|
|
|
|
|
|
reserved. |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
You may distribute under the terms of either the GNU General Public License |
629
|
|
|
|
|
|
|
or the Artistic License, as specified in the Perl README file. |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
=head1 AUTHORS |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
Nigel Rantor > |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
=head1 SEE ALSO |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
L. |
638
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
=cut |