diff options
Diffstat (limited to 'Documentation/java.txt')
-rw-r--r-- | Documentation/java.txt | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/Documentation/java.txt b/Documentation/java.txt new file mode 100644 index 000000000000..e4814c213301 --- /dev/null +++ b/Documentation/java.txt | |||
@@ -0,0 +1,396 @@ | |||
1 | Java(tm) Binary Kernel Support for Linux v1.03 | ||
2 | ---------------------------------------------- | ||
3 | |||
4 | Linux beats them ALL! While all other OS's are TALKING about direct | ||
5 | support of Java Binaries in the OS, Linux is doing it! | ||
6 | |||
7 | You can execute Java applications and Java Applets just like any | ||
8 | other program after you have done the following: | ||
9 | |||
10 | 1) You MUST FIRST install the Java Developers Kit for Linux. | ||
11 | The Java on Linux HOWTO gives the details on getting and | ||
12 | installing this. This HOWTO can be found at: | ||
13 | |||
14 | ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/Java-HOWTO | ||
15 | |||
16 | You should also set up a reasonable CLASSPATH environment | ||
17 | variable to use Java applications that make use of any | ||
18 | nonstandard classes (not included in the same directory | ||
19 | as the application itself). | ||
20 | |||
21 | 2) You have to compile BINFMT_MISC either as a module or into | ||
22 | the kernel (CONFIG_BINFMT_MISC) and set it up properly. | ||
23 | If you choose to compile it as a module, you will have | ||
24 | to insert it manually with modprobe/insmod, as kmod | ||
25 | can not easily be supported with binfmt_misc. | ||
26 | Read the file 'binfmt_misc.txt' in this directory to know | ||
27 | more about the configuration process. | ||
28 | |||
29 | 3) Add the following configuration items to binfmt_misc | ||
30 | (you should really have read binfmt_misc.txt now): | ||
31 | support for Java applications: | ||
32 | ':Java:M::\xca\xfe\xba\xbe::/usr/local/bin/javawrapper:' | ||
33 | support for executable Jar files: | ||
34 | ':ExecutableJAR:E::jar::/usr/local/bin/jarwrapper:' | ||
35 | support for Java Applets: | ||
36 | ':Applet:E::html::/usr/bin/appletviewer:' | ||
37 | or the following, if you want to be more selective: | ||
38 | ':Applet:M::<!--applet::/usr/bin/appletviewer:' | ||
39 | |||
40 | Of cause you have to fix the path names. Given path/file names in this | ||
41 | document match the Debian 2.1 system. (i.e. jdk installed in /usr, | ||
42 | custom wrappers from this document in /usr/local) | ||
43 | |||
44 | Note, that for the more selective applet support you have to modify | ||
45 | existing html-files to contain <!--applet--> in the first line | ||
46 | ('<' has to be the first character!) to let this work! | ||
47 | |||
48 | For the compiled Java programs you need a wrapper script like the | ||
49 | following (this is because Java is broken in case of the filename | ||
50 | handling), again fix the path names, both in the script and in the | ||
51 | above given configuration string. | ||
52 | |||
53 | You, too, need the little program after the script. Compile like | ||
54 | gcc -O2 -o javaclassname javaclassname.c | ||
55 | and stick it to /usr/local/bin. | ||
56 | |||
57 | Both the javawrapper shellscript and the javaclassname program | ||
58 | were supplied by Colin J. Watson <cjw44@cam.ac.uk>. | ||
59 | |||
60 | ====================== Cut here =================== | ||
61 | #!/bin/bash | ||
62 | # /usr/local/bin/javawrapper - the wrapper for binfmt_misc/java | ||
63 | |||
64 | if [ -z "$1" ]; then | ||
65 | exec 1>&2 | ||
66 | echo Usage: $0 class-file | ||
67 | exit 1 | ||
68 | fi | ||
69 | |||
70 | CLASS=$1 | ||
71 | FQCLASS=`/usr/local/bin/javaclassname $1` | ||
72 | FQCLASSN=`echo $FQCLASS | sed -e 's/^.*\.\([^.]*\)$/\1/'` | ||
73 | FQCLASSP=`echo $FQCLASS | sed -e 's-\.-/-g' -e 's-^[^/]*$--' -e 's-/[^/]*$--'` | ||
74 | |||
75 | # for example: | ||
76 | # CLASS=Test.class | ||
77 | # FQCLASS=foo.bar.Test | ||
78 | # FQCLASSN=Test | ||
79 | # FQCLASSP=foo/bar | ||
80 | |||
81 | unset CLASSBASE | ||
82 | |||
83 | declare -i LINKLEVEL=0 | ||
84 | |||
85 | while :; do | ||
86 | if [ "`basename $CLASS .class`" == "$FQCLASSN" ]; then | ||
87 | # See if this directory works straight off | ||
88 | cd -L `dirname $CLASS` | ||
89 | CLASSDIR=$PWD | ||
90 | cd $OLDPWD | ||
91 | if echo $CLASSDIR | grep -q "$FQCLASSP$"; then | ||
92 | CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."` | ||
93 | break; | ||
94 | fi | ||
95 | # Try dereferencing the directory name | ||
96 | cd -P `dirname $CLASS` | ||
97 | CLASSDIR=$PWD | ||
98 | cd $OLDPWD | ||
99 | if echo $CLASSDIR | grep -q "$FQCLASSP$"; then | ||
100 | CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."` | ||
101 | break; | ||
102 | fi | ||
103 | # If no other possible filename exists | ||
104 | if [ ! -L $CLASS ]; then | ||
105 | exec 1>&2 | ||
106 | echo $0: | ||
107 | echo " $CLASS should be in a" \ | ||
108 | "directory tree called $FQCLASSP" | ||
109 | exit 1 | ||
110 | fi | ||
111 | fi | ||
112 | if [ ! -L $CLASS ]; then break; fi | ||
113 | # Go down one more level of symbolic links | ||
114 | let LINKLEVEL+=1 | ||
115 | if [ $LINKLEVEL -gt 5 ]; then | ||
116 | exec 1>&2 | ||
117 | echo $0: | ||
118 | echo " Too many symbolic links encountered" | ||
119 | exit 1 | ||
120 | fi | ||
121 | CLASS=`ls --color=no -l $CLASS | sed -e 's/^.* \([^ ]*\)$/\1/'` | ||
122 | done | ||
123 | |||
124 | if [ -z "$CLASSBASE" ]; then | ||
125 | if [ -z "$FQCLASSP" ]; then | ||
126 | GOODNAME=$FQCLASSN.class | ||
127 | else | ||
128 | GOODNAME=$FQCLASSP/$FQCLASSN.class | ||
129 | fi | ||
130 | exec 1>&2 | ||
131 | echo $0: | ||
132 | echo " $FQCLASS should be in a file called $GOODNAME" | ||
133 | exit 1 | ||
134 | fi | ||
135 | |||
136 | if ! echo $CLASSPATH | grep -q "^\(.*:\)*$CLASSBASE\(:.*\)*"; then | ||
137 | # class is not in CLASSPATH, so prepend dir of class to CLASSPATH | ||
138 | if [ -z "${CLASSPATH}" ] ; then | ||
139 | export CLASSPATH=$CLASSBASE | ||
140 | else | ||
141 | export CLASSPATH=$CLASSBASE:$CLASSPATH | ||
142 | fi | ||
143 | fi | ||
144 | |||
145 | shift | ||
146 | /usr/bin/java $FQCLASS "$@" | ||
147 | ====================== Cut here =================== | ||
148 | |||
149 | |||
150 | ====================== Cut here =================== | ||
151 | /* javaclassname.c | ||
152 | * | ||
153 | * Extracts the class name from a Java class file; intended for use in a Java | ||
154 | * wrapper of the type supported by the binfmt_misc option in the Linux kernel. | ||
155 | * | ||
156 | * Copyright (C) 1999 Colin J. Watson <cjw44@cam.ac.uk>. | ||
157 | * | ||
158 | * This program is free software; you can redistribute it and/or modify | ||
159 | * it under the terms of the GNU General Public License as published by | ||
160 | * the Free Software Foundation; either version 2 of the License, or | ||
161 | * (at your option) any later version. | ||
162 | * | ||
163 | * This program is distributed in the hope that it will be useful, | ||
164 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
165 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
166 | * GNU General Public License for more details. | ||
167 | * | ||
168 | * You should have received a copy of the GNU General Public License | ||
169 | * along with this program; if not, write to the Free Software | ||
170 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
171 | */ | ||
172 | |||
173 | #include <stdlib.h> | ||
174 | #include <stdio.h> | ||
175 | #include <stdarg.h> | ||
176 | #include <sys/types.h> | ||
177 | |||
178 | /* From Sun's Java VM Specification, as tag entries in the constant pool. */ | ||
179 | |||
180 | #define CP_UTF8 1 | ||
181 | #define CP_INTEGER 3 | ||
182 | #define CP_FLOAT 4 | ||
183 | #define CP_LONG 5 | ||
184 | #define CP_DOUBLE 6 | ||
185 | #define CP_CLASS 7 | ||
186 | #define CP_STRING 8 | ||
187 | #define CP_FIELDREF 9 | ||
188 | #define CP_METHODREF 10 | ||
189 | #define CP_INTERFACEMETHODREF 11 | ||
190 | #define CP_NAMEANDTYPE 12 | ||
191 | |||
192 | /* Define some commonly used error messages */ | ||
193 | |||
194 | #define seek_error() error("%s: Cannot seek\n", program) | ||
195 | #define corrupt_error() error("%s: Class file corrupt\n", program) | ||
196 | #define eof_error() error("%s: Unexpected end of file\n", program) | ||
197 | #define utf8_error() error("%s: Only ASCII 1-255 supported\n", program); | ||
198 | |||
199 | char *program; | ||
200 | |||
201 | long *pool; | ||
202 | |||
203 | u_int8_t read_8(FILE *classfile); | ||
204 | u_int16_t read_16(FILE *classfile); | ||
205 | void skip_constant(FILE *classfile, u_int16_t *cur); | ||
206 | void error(const char *format, ...); | ||
207 | int main(int argc, char **argv); | ||
208 | |||
209 | /* Reads in an unsigned 8-bit integer. */ | ||
210 | u_int8_t read_8(FILE *classfile) | ||
211 | { | ||
212 | int b = fgetc(classfile); | ||
213 | if(b == EOF) | ||
214 | eof_error(); | ||
215 | return (u_int8_t)b; | ||
216 | } | ||
217 | |||
218 | /* Reads in an unsigned 16-bit integer. */ | ||
219 | u_int16_t read_16(FILE *classfile) | ||
220 | { | ||
221 | int b1, b2; | ||
222 | b1 = fgetc(classfile); | ||
223 | if(b1 == EOF) | ||
224 | eof_error(); | ||
225 | b2 = fgetc(classfile); | ||
226 | if(b2 == EOF) | ||
227 | eof_error(); | ||
228 | return (u_int16_t)((b1 << 8) | b2); | ||
229 | } | ||
230 | |||
231 | /* Reads in a value from the constant pool. */ | ||
232 | void skip_constant(FILE *classfile, u_int16_t *cur) | ||
233 | { | ||
234 | u_int16_t len; | ||
235 | int seekerr = 1; | ||
236 | pool[*cur] = ftell(classfile); | ||
237 | switch(read_8(classfile)) | ||
238 | { | ||
239 | case CP_UTF8: | ||
240 | len = read_16(classfile); | ||
241 | seekerr = fseek(classfile, len, SEEK_CUR); | ||
242 | break; | ||
243 | case CP_CLASS: | ||
244 | case CP_STRING: | ||
245 | seekerr = fseek(classfile, 2, SEEK_CUR); | ||
246 | break; | ||
247 | case CP_INTEGER: | ||
248 | case CP_FLOAT: | ||
249 | case CP_FIELDREF: | ||
250 | case CP_METHODREF: | ||
251 | case CP_INTERFACEMETHODREF: | ||
252 | case CP_NAMEANDTYPE: | ||
253 | seekerr = fseek(classfile, 4, SEEK_CUR); | ||
254 | break; | ||
255 | case CP_LONG: | ||
256 | case CP_DOUBLE: | ||
257 | seekerr = fseek(classfile, 8, SEEK_CUR); | ||
258 | ++(*cur); | ||
259 | break; | ||
260 | default: | ||
261 | corrupt_error(); | ||
262 | } | ||
263 | if(seekerr) | ||
264 | seek_error(); | ||
265 | } | ||
266 | |||
267 | void error(const char *format, ...) | ||
268 | { | ||
269 | va_list ap; | ||
270 | va_start(ap, format); | ||
271 | vfprintf(stderr, format, ap); | ||
272 | va_end(ap); | ||
273 | exit(1); | ||
274 | } | ||
275 | |||
276 | int main(int argc, char **argv) | ||
277 | { | ||
278 | FILE *classfile; | ||
279 | u_int16_t cp_count, i, this_class, classinfo_ptr; | ||
280 | u_int8_t length; | ||
281 | |||
282 | program = argv[0]; | ||
283 | |||
284 | if(!argv[1]) | ||
285 | error("%s: Missing input file\n", program); | ||
286 | classfile = fopen(argv[1], "rb"); | ||
287 | if(!classfile) | ||
288 | error("%s: Error opening %s\n", program, argv[1]); | ||
289 | |||
290 | if(fseek(classfile, 8, SEEK_SET)) /* skip magic and version numbers */ | ||
291 | seek_error(); | ||
292 | cp_count = read_16(classfile); | ||
293 | pool = calloc(cp_count, sizeof(long)); | ||
294 | if(!pool) | ||
295 | error("%s: Out of memory for constant pool\n", program); | ||
296 | |||
297 | for(i = 1; i < cp_count; ++i) | ||
298 | skip_constant(classfile, &i); | ||
299 | if(fseek(classfile, 2, SEEK_CUR)) /* skip access flags */ | ||
300 | seek_error(); | ||
301 | |||
302 | this_class = read_16(classfile); | ||
303 | if(this_class < 1 || this_class >= cp_count) | ||
304 | corrupt_error(); | ||
305 | if(!pool[this_class] || pool[this_class] == -1) | ||
306 | corrupt_error(); | ||
307 | if(fseek(classfile, pool[this_class] + 1, SEEK_SET)) | ||
308 | seek_error(); | ||
309 | |||
310 | classinfo_ptr = read_16(classfile); | ||
311 | if(classinfo_ptr < 1 || classinfo_ptr >= cp_count) | ||
312 | corrupt_error(); | ||
313 | if(!pool[classinfo_ptr] || pool[classinfo_ptr] == -1) | ||
314 | corrupt_error(); | ||
315 | if(fseek(classfile, pool[classinfo_ptr] + 1, SEEK_SET)) | ||
316 | seek_error(); | ||
317 | |||
318 | length = read_16(classfile); | ||
319 | for(i = 0; i < length; ++i) | ||
320 | { | ||
321 | u_int8_t x = read_8(classfile); | ||
322 | if((x & 0x80) || !x) | ||
323 | { | ||
324 | if((x & 0xE0) == 0xC0) | ||
325 | { | ||
326 | u_int8_t y = read_8(classfile); | ||
327 | if((y & 0xC0) == 0x80) | ||
328 | { | ||
329 | int c = ((x & 0x1f) << 6) + (y & 0x3f); | ||
330 | if(c) putchar(c); | ||
331 | else utf8_error(); | ||
332 | } | ||
333 | else utf8_error(); | ||
334 | } | ||
335 | else utf8_error(); | ||
336 | } | ||
337 | else if(x == '/') putchar('.'); | ||
338 | else putchar(x); | ||
339 | } | ||
340 | putchar('\n'); | ||
341 | free(pool); | ||
342 | fclose(classfile); | ||
343 | return 0; | ||
344 | } | ||
345 | ====================== Cut here =================== | ||
346 | |||
347 | |||
348 | ====================== Cut here =================== | ||
349 | #!/bin/bash | ||
350 | # /usr/local/java/bin/jarwrapper - the wrapper for binfmt_misc/jar | ||
351 | |||
352 | java -jar $1 | ||
353 | ====================== Cut here =================== | ||
354 | |||
355 | |||
356 | Now simply chmod +x the .class, .jar and/or .html files you want to execute. | ||
357 | To add a Java program to your path best put a symbolic link to the main | ||
358 | .class file into /usr/bin (or another place you like) omitting the .class | ||
359 | extension. The directory containing the original .class file will be | ||
360 | added to your CLASSPATH during execution. | ||
361 | |||
362 | |||
363 | To test your new setup, enter in the following simple Java app, and name | ||
364 | it "HelloWorld.java": | ||
365 | |||
366 | class HelloWorld { | ||
367 | public static void main(String args[]) { | ||
368 | System.out.println("Hello World!"); | ||
369 | } | ||
370 | } | ||
371 | |||
372 | Now compile the application with: | ||
373 | javac HelloWorld.java | ||
374 | |||
375 | Set the executable permissions of the binary file, with: | ||
376 | chmod 755 HelloWorld.class | ||
377 | |||
378 | And then execute it: | ||
379 | ./HelloWorld.class | ||
380 | |||
381 | |||
382 | To execute Java Jar files, simple chmod the *.jar files to include | ||
383 | the execution bit, then just do | ||
384 | ./Application.jar | ||
385 | |||
386 | |||
387 | To execute Java Applets, simple chmod the *.html files to include | ||
388 | the execution bit, then just do | ||
389 | ./Applet.html | ||
390 | |||
391 | |||
392 | originally by Brian A. Lantz, brian@lantz.com | ||
393 | heavily edited for binfmt_misc by Richard Günther | ||
394 | new scripts by Colin J. Watson <cjw44@cam.ac.uk> | ||
395 | added executable Jar file support by Kurt Huwig <kurt@iku-netz.de> | ||
396 | |||