|
1
|
#!/bin/bash
|
|
2
|
|
|
3
|
#set -x
|
|
4
|
|
|
5
|
# standard FWD interactive client startup script
|
|
6
|
|
|
7
|
# defaults
|
|
8
|
whole_path="$(cd "$(dirname "$0")"; pwd)/$(basename "$0")"
|
|
9
|
srcname=$(basename "$whole_path")
|
|
10
|
srcpath=$(dirname "$whole_path")
|
|
11
|
[ ! -f ${srcpath}/appname ] && echo "FATAL: No appname to source in $srcpath" && exit
|
|
12
|
[ -z "$appname" ] && . ${srcpath}/appname
|
|
13
|
suspend="n"
|
|
14
|
prog="java"
|
|
15
|
dump="-XX:+HeapDumpOnOutOfMemoryError"
|
|
16
|
#dump="-XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError='./stack_dump.sh %p'"
|
|
17
|
host="net:server:host=localhost"
|
|
18
|
batch_parms="client:mode:batch=true client:driver:background=true"
|
|
19
|
driver_type="gui"
|
|
20
|
instance=0
|
|
21
|
portbase=3333
|
|
22
|
secure=false
|
|
23
|
portstep=100
|
|
24
|
maxheap=""
|
|
25
|
# Set this to debug the ssl handshake and include in jvm parms
|
|
26
|
#ssl_debug="-Djavax.net.debug=ssl:handshake"
|
|
27
|
|
|
28
|
# Determine the configured JDK
|
|
29
|
#jver is 18 for java 1.8, 15 for java 1.5, 110 for java 11, 170 for java 17 etc.
|
|
30
|
jver=$(${prog} -version 2>&1 | awk -F '"' '/version/ {print $2}' | awk -F '.' '{sub("^$", "0", $2); print $1$2}')
|
|
31
|
|
|
32
|
# Ensure UTF-8 is set
|
|
33
|
ensure_utf8_lang()
|
|
34
|
{
|
|
35
|
# Get the current LANG setting and encoding portion (after the dot '.')
|
|
36
|
current_lang="${LANG}"
|
|
37
|
encoding="${current_lang##*.}"
|
|
38
|
|
|
39
|
shopt -s nocasematch
|
|
40
|
# Check if the encoding is not UTF-8
|
|
41
|
if [[ ! "$encoding" =~ ^utf-?8$ ]]; then
|
|
42
|
# Warn the user
|
|
43
|
echo "Warning: The current LANG setting (${current_lang}) is not using UTF-8 encoding."
|
|
44
|
|
|
45
|
# Set LANG to LANGUAGE.UTF-8, or fallback to en_US.UTF-8 if LANGUAGE is not set
|
|
46
|
[ -z "$LANGUAGE" ] && new_lang="en_US.UTF-8" || new_lang="${LANGUAGE}.UTF-8"
|
|
47
|
|
|
48
|
# Apply the new LANG setting
|
|
49
|
export LANG="$new_lang"
|
|
50
|
|
|
51
|
# Inform the user
|
|
52
|
echo "LANG has been updated to: ${LANG}"
|
|
53
|
fi
|
|
54
|
shopt -u nocasematch
|
|
55
|
}
|
|
56
|
|
|
57
|
# help text
|
|
58
|
show_usage()
|
|
59
|
{
|
|
60
|
i=0; usage[$i]="\nUsage: $0 [-d<port>] [-s] [-c<cfgfile>] [-i<instance>] [-m<path>] [-2] [-b] [-k<password>] [-t<password>] [-p<procedure>] [-x<heap>] [-o<cmd-line-option:params>] [--test] [--wb] [--swing] [--terminal] \n"
|
|
61
|
i=$((i+1)); usage[$i]="Where:\n"
|
|
62
|
i=$((i+1)); usage[$i]="d \t= enable JVM debug mode, use the specified TCP port"
|
|
63
|
i=$((i+1)); usage[$i]="s \t= in JVM debug mode enable, suspend the JVM on startup (does not suspend by default)"
|
|
64
|
i=$((i+1)); usage[$i]="h \t= hostname or IP address for the server (defaults to localhost)"
|
|
65
|
i=$((i+1)); usage[$i]="i \t= server instance number (0..9, assigns the FWD server port, defaults to 0) to which to connect"
|
|
66
|
i=$((i+1)); usage[$i]="m \t= Enable heap dump on OOME to given path"
|
|
67
|
i=$((i+1)); usage[$i]="c \t= config file name (FWD bootstrap config file name, defaults to standard_client.xml)"
|
|
68
|
i=$((i+1)); usage[$i]="2 \t= enable C2 HotSpot compiler (server compiler for the JVM)"
|
|
69
|
i=$((i+1)); usage[$i]="b \t= run with client in batch mode (forces --terminal)"
|
|
70
|
i=$((i+1)); usage[$i]="k \t= password for keystore"
|
|
71
|
i=$((i+1)); usage[$i]="t \t= password for trust"
|
|
72
|
i=$((i+1)); usage[$i]="p \t= procedure to run"
|
|
73
|
i=$((i+1)); usage[$i]="x \t= set JVM max heap size to <heap> (must be an integer number of MB)"
|
|
74
|
i=$((i+1)); usage[$i]="o \t= options (params) to pass to cmd-line-option:params. Make sure this is the last on the command line, and in \"\""
|
|
75
|
i=$((i+1)); usage[$i]="--test \t\t= test mode (displays the command but doesn't execute)"
|
|
76
|
i=$((i+1)); usage[$i]="--wb \t\t= enable widget browser for debug purposes"
|
|
77
|
i=$((i+1)); usage[$i]="--swing \t= use Swing client"
|
|
78
|
i=$((i+1)); usage[$i]="--terminal\t= use ChUI driver"
|
|
79
|
i=$((i+1)); usage[$i]="--no-appcds\t= disable AppCDS: full classpath discovery, no shared archive (pre-AppCDS behavior)"
|
|
80
|
|
|
81
|
for i in "${usage[@]}"; do
|
|
82
|
echo -e $i
|
|
83
|
done
|
|
84
|
}
|
|
85
|
|
|
86
|
# process options
|
|
87
|
while getopts "?d:sh:i:m:c:2bk:t:p:o:x:-:" opt; do
|
|
88
|
case $opt in
|
|
89
|
d ) debug=true
|
|
90
|
dport=$OPTARG ;;
|
|
91
|
s ) suspend="y" ;;
|
|
92
|
h ) host="net:server:host="$OPTARG ;;
|
|
93
|
i ) instance=$OPTARG ;;
|
|
94
|
m ) dump+=" -XX:HeapDumpPath=${OPTARG}" ;;
|
|
95
|
c ) cfg=$OPTARG ;;
|
|
96
|
2 ) srvr="-server" ;;
|
|
97
|
b ) batch="${batch_parms}"
|
|
98
|
use_terminal=true ;;
|
|
99
|
k ) kpasswd=$OPTARG ;;
|
|
100
|
t ) tpasswd=$OPTARG ;;
|
|
101
|
p ) procedure=$OPTARG ;;
|
|
102
|
x ) maxheap="-Xmx"${OPTARG}"m" ;;
|
|
103
|
o ) # Save the remaining command-line arguments into 'params'
|
|
104
|
shift $((OPTIND - 2)) # Shift to the first argument after '-o'
|
|
105
|
params=$* # Capture all remaining text
|
|
106
|
break # Exit the loop as we are done
|
|
107
|
;;
|
|
108
|
- ) case ${OPTARG} in
|
|
109
|
test ) test=true ;;
|
|
110
|
wb ) wb="-Dwidget.browser=true" ;;
|
|
111
|
swing ) use_swing=true ;;
|
|
112
|
terminal ) use_terminal=true
|
|
113
|
driver_type="chui" ;;
|
|
114
|
no-appcds ) no_appcds=true ;;
|
|
115
|
esac ;;
|
|
116
|
\? ) show_usage
|
|
117
|
exit 1 ;;
|
|
118
|
esac
|
|
119
|
done
|
|
120
|
shift $(($OPTIND - 1))
|
|
121
|
|
|
122
|
# Determine driver and token
|
|
123
|
if [ "$use_swing" == true ]; then
|
|
124
|
client_driver_type="client:driver:type=${driver_type}_swing"
|
|
125
|
if [ "$use_terminal" == true ]; then
|
|
126
|
client_driver_type+=" client:chui:rows=24 client:chui:columns=80 client:chui:background=0x000000 client:chui:foreground=0xFFA500 client:chui:selection=0x0000FF client:chui:fontname=monospaced client:chui:fontsize=12"
|
|
127
|
fi
|
|
128
|
else
|
|
129
|
if [ "$use_terminal" == true ]; then
|
|
130
|
client_driver_type="client:driver:type=${driver_type}_native"
|
|
131
|
else
|
|
132
|
client_driver_type="client:driver:type=${driver_type}_swing"
|
|
133
|
fi
|
|
134
|
fi
|
|
135
|
token="client:project:token=${driver_type}"
|
|
136
|
if [ -n "$batch" ]; then
|
|
137
|
secure=true
|
|
138
|
unset client_driver_type
|
|
139
|
fi
|
|
140
|
|
|
141
|
# pass the remaining command line arguments directly to the java driver
|
|
142
|
# WARNING: any arguments with embedded spaces are not passed properly; for
|
|
143
|
# example, if you pass this to the script:
|
|
144
|
# client:cmd-line-option:parameter="\"\\\"some text here\\\"\""
|
|
145
|
# you would expect the following to be passed to the java driver:
|
|
146
|
# client:cmd-line-option:parameter="\"some text here\""
|
|
147
|
# but that does not happen; when running the driver directly this would
|
|
148
|
# work fine; via the script the result is that the driver sees add'l
|
|
149
|
# parameters, which will cause it to think it has add'l bootstrap config
|
|
150
|
# files to load
|
|
151
|
if [ -z "$params" ]; then
|
|
152
|
remainder="$@"
|
|
153
|
fi
|
|
154
|
|
|
155
|
# final arg prep
|
|
156
|
sport=$(($portbase + $instance))
|
|
157
|
iport=$(($portbase + $instance + $portstep))
|
|
158
|
port="net:connection:secure=${secure} net:server:secure_port=$sport net:server:insecure_port=$iport"
|
|
159
|
|
|
160
|
# Prevent NIO sockets
|
|
161
|
nio="net:socket:nio=false"
|
|
162
|
|
|
163
|
if [ "$debug" == true ]; then
|
|
164
|
[ -f "/.dockerenv" ] && daddress="0.0.0.0:${dport}" || daddress="${dport}"
|
|
165
|
dtxt="-agentlib:jdwp=transport=dt_socket,server=y,suspend=${suspend},address=${daddress}"
|
|
166
|
fi
|
|
167
|
|
|
168
|
if [ -n "$cfg" ]; then
|
|
169
|
# Path could be relative to the srcpath, so calculate it and test existence.
|
|
170
|
p=$(cd $(dirname ${srcpath}/${cfg}) 2>/dev/null; echo $(pwd))
|
|
171
|
f=$(basename $cfg)
|
|
172
|
[ -f "${p}/${f}" ] && cfg="${p}/${f}"
|
|
173
|
token=""
|
|
174
|
host=""
|
|
175
|
fi
|
|
176
|
|
|
177
|
# Server with store
|
|
178
|
if [ -n "$tpasswd" ]; then
|
|
179
|
tpasswd="ssl-socket:truststore:password=${tpasswd}"
|
|
180
|
fi
|
|
181
|
# Connect with trust
|
|
182
|
if [ -n "$kpasswd" ]; then
|
|
183
|
kpasswd="ssl-socket:keystore:password=${kpasswd}"
|
|
184
|
fi
|
|
185
|
|
|
186
|
# Pass in: client:cmd-line-option:startup-procedure=<file.p>
|
|
187
|
if [ -n "$procedure" ]; then
|
|
188
|
procedure="client:cmd-line-option:startup-procedure=${procedure}"
|
|
189
|
fi
|
|
190
|
|
|
191
|
# Pass in options (params): client:cmd-line-option:parameter=<params>
|
|
192
|
if [ -n "$params" ]; then
|
|
193
|
params="'client:cmd-line-option:parameter=${params}'"
|
|
194
|
fi
|
|
195
|
|
|
196
|
# getcp.sh and getspi.sh are helpers for setting up the classpath and spi for the given application.
|
|
197
|
# This allows more flexibility in where the FWD configuration is placed. It can be one directory up,
|
|
198
|
# and then in lib, or in /opt/fwd/lib, or specified by FWD_LIB exported or up to the build directory,
|
|
199
|
# then down to lib. If the helper isn't found, we can only fall back to the original method.
|
|
200
|
helper=$(cd ${srcpath}/..; echo $(pwd))
|
|
201
|
export PATH=$helper:$PATH
|
|
202
|
if command -v getcp.sh >/dev/null 2>&1; then
|
|
203
|
# --appcds tells getcp.sh to prefer the curated client classpath published by
|
|
204
|
# deploy_appcds.sh (appcds/client/<type>.cpath), matching the AppCDS archive.
|
|
205
|
# It falls back to the normal FWD library discovery when no curated file
|
|
206
|
# exists, so this is safe on deployments without AppCDS. With --no-appcds we
|
|
207
|
# omit the flag so getcp.sh does full FWD library discovery (pre-AppCDS behavior).
|
|
208
|
appcds_flag="--appcds"
|
|
209
|
[ "$no_appcds" == true ] && appcds_flag=""
|
|
210
|
cpath=$(getcp.sh $appname $srcpath $appcds_flag)
|
|
211
|
lpath="-Djava.library.path="$(getspi.sh "$cpath" "p2j.jar")
|
|
212
|
cpath="-classpath $cpath"
|
|
213
|
else
|
|
214
|
# getcp.sh not available: build the classpath here, but still honor AppCDS so the
|
|
215
|
# archive can map. Mirror getcp.sh --appcds: if a curated <type>.cpath exists (and
|
|
216
|
# AppCDS isn't disabled) use it verbatim so the classpath matches the dumped
|
|
217
|
# archive; otherwise fall back to globbing ../lib.
|
|
218
|
appcds_type="default"
|
|
219
|
appcds_cpath=""
|
|
220
|
if [ "$no_appcds" != true ]; then
|
|
221
|
cand="${srcpath}/../appcds/client/${appcds_type}.cpath"
|
|
222
|
[ -f "$cand" ] && appcds_cpath="$(cat "$cand")"
|
|
223
|
fi
|
|
224
|
if [ -n "$appcds_cpath" ]; then
|
|
225
|
cpath="$appcds_cpath"
|
|
226
|
else
|
|
227
|
cpath="../lib/p2j.jar"
|
|
228
|
for each in ../lib/*.jar; do
|
|
229
|
[ "$each" = "../lib/p2j.jar" ] || cpath="$cpath:$each"
|
|
230
|
done
|
|
231
|
fi
|
|
232
|
lpath="-Djava.library.path=../lib/"
|
|
233
|
cpath="-classpath $cpath"
|
|
234
|
fi
|
|
235
|
|
|
236
|
# Enable AppCDS for the client when a curated archive is present. This is the
|
|
237
|
# complement to the curated classpath above: -XX:SharedArchiveFile points the JVM
|
|
238
|
# at the pre-parsed class archive built by deploy_appcds.sh, while the classpath
|
|
239
|
# (from getcp.sh --appcds) determines which jars are actually loaded. They are
|
|
240
|
# independent JVM inputs -- the archive only accelerates classes that are also on
|
|
241
|
# the classpath, and -Xshare:auto silently ignores the archive if the runtime
|
|
242
|
# classpath does not match the one it was dumped against. This mirrors the
|
|
243
|
# webClient jvmArgs in directory.xml and the cdsparams assembled in server.sh.
|
|
244
|
appcds_type="default"
|
|
245
|
cdsparams=""
|
|
246
|
if [ "$no_appcds" != true ]; then
|
|
247
|
cand="${srcpath}/../appcds/client/${appcds_type}.jsa"
|
|
248
|
if [ -f "$cand" ]; then
|
|
249
|
[ "$debug" == true ] && p="-Xshare:on -Xlog:class+path=info" || p="-Xshare:auto"
|
|
250
|
cdsparams="${p} -XX:SharedArchiveFile=$cand"
|
|
251
|
fi
|
|
252
|
fi
|
|
253
|
|
|
254
|
# Ensure UTF-8 encoding
|
|
255
|
original_lang="${LANG}"
|
|
256
|
ensure_utf8_lang
|
|
257
|
|
|
258
|
# run the FWD client
|
|
259
|
java_args="$srvr $maxheap $dump $wb $dtxt $lpath $cpath $cdsparams"
|
|
260
|
|
|
261
|
# Compatibility with Java 25
|
|
262
|
if [ $jver -ge 240 ]; then
|
|
263
|
java_args+=" --enable-native-access=ALL-UNNAMED"
|
|
264
|
fi
|
|
265
|
|
|
266
|
client_driver_args="$kpasswd $tpasswd $token $host $nio $port $client_driver_type $cfg $batch $procedure $params $remainder"
|
|
267
|
cmd="$prog $java_args com.goldencode.p2j.main.ClientDriver $client_driver_args"
|
|
268
|
if [ "$test" == "true" ]; then
|
|
269
|
echo $cmd
|
|
270
|
else
|
|
271
|
eval $cmd
|
|
272
|
fi
|
|
273
|
|
|
274
|
# Restore the original LANG setting, if sourced ad set
|
|
275
|
[ "${BASH_SOURCE[0]}" != "${0}" ] && [ ."$original_lang". != ".." ] && export LANG="$original_lang"
|
|
276
|
|