Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / Documentation / java.txt
blobbe7203d3b0a1ef479d5d9ac493e6fbe98d9fcc74
1                Java(tm) Binary Kernel Support for Linux v1.02
2                ----------------------------------------------
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!
7 You can execute Java applications and Java Applets just like any
8 other program after you have done the following:
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:
14         ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/Java-HOWTO
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).
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 easy be supported with binfmt_misc. 
26    Read the file 'binfmt_misc.txt' in this directory to know
27    more about the configuration process.
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 Java Applets:
34      ':Applet:E::html::/usr/bin/appletviewer:'
35    or the following, if you want to be more selective:
36      ':Applet:M::<!--applet::/usr/bin/appletviewer:'
38    Of cause you have to fix the path names. Given path/file names in this
39    document match the Debian 2.1 system. (i.e. jdk installed in /usr,
40    custom wrappers from this document in /usr/local)
42    Note, that for the more selective applet support you have to modify
43    existing html-files to contain <!--applet--> in the first line
44    ('<' has to be the first character!) to let this work!
46    For the compiled Java programs you need a wrapper script like the
47    following (this is because Java is broken in case of the filename
48    handling), again fix the path names, both in the script and in the
49    above given configuration string.
51    You, too, need the little program after the script. Compile like
52    gcc -O2 -o javaclassname javaclassname.c
53    and stick it to /usr/local/bin.
55    Both the javawrapper shellscript and the javaclassname program
56    were supplied by Colin J. Watson <cjw44@cam.ac.uk>.
58 ====================== Cut here ===================
59 #!/bin/bash
60 # /usr/local/bin/javawrapper - the wrapper for binfmt_misc/java
62 if [ -z "$1" ]; then
63         exec 1>&2
64         echo Usage: $0 class-file
65         exit 1
68 CLASS=$1
69 FQCLASS=`/usr/local/bin/javaclassname $1`
70 FQCLASSN=`echo $FQCLASS | sed -e 's/^.*\.\([^.]*\)$/\1/'`
71 FQCLASSP=`echo $FQCLASS | sed -e 's-\.-/-g' -e 's-^[^/]*$--' -e 's-/[^/]*$--'`
73 # for example:
74 # CLASS=Test.class
75 # FQCLASS=foo.bar.Test
76 # FQCLASSN=Test
77 # FQCLASSP=foo/bar
79 unset CLASSBASE
81 declare -i LINKLEVEL=0
83 while :; do
84         if [ "`basename $CLASS .class`" == "$FQCLASSN" ]; then
85                 # See if this directory works straight off
86                 cd -L `dirname $CLASS`
87                 CLASSDIR=$PWD
88                 cd $OLDPWD
89                 if echo $CLASSDIR | grep -q "$FQCLASSP$"; then
90                         CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."`
91                         break;
92                 fi
93                 # Try dereferencing the directory name
94                 cd -P `dirname $CLASS`
95                 CLASSDIR=$PWD
96                 cd $OLDPWD
97                 if echo $CLASSDIR | grep -q "$FQCLASSP$"; then
98                         CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."`
99                         break;
100                 fi
101                 # If no other possible filename exists
102                 if [ ! -L $CLASS ]; then
103                         exec 1>&2
104                         echo $0:
105                         echo "  $CLASS should be in a" \
106                              "directory tree called $FQCLASSP"
107                         exit 1
108                 fi
109         fi
110         if [ ! -L $CLASS ]; then break; fi
111         # Go down one more level of symbolic links
112         let LINKLEVEL+=1
113         if [ $LINKLEVEL -gt 5 ]; then
114                 exec 1>&2
115                 echo $0:
116                 echo "  Too many symbolic links encountered"
117                 exit 1
118         fi
119         CLASS=`ls --color=no -l $CLASS | sed -e 's/^.* \([^ ]*\)$/\1/'`
120 done
122 if [ -z "$CLASSBASE" ]; then
123         if [ -z "$FQCLASSP" ]; then
124                 GOODNAME=$FQCLASSN.class
125         else
126                 GOODNAME=$FQCLASSP/$FQCLASSN.class
127         fi
128         exec 1>&2
129         echo $0:
130         echo "  $FQCLASS should be in a file called $GOODNAME"
131         exit 1
134 if ! echo $CLASSPATH | grep -q "^\(.*:\)*$CLASSBASE\(:.*\)*"; then
135         # class is not in CLASSPATH, so prepend dir of class to CLASSPATH
136         if [ -z "${CLASSPATH}" ] ; then
137                 export CLASSPATH=$CLASSBASE
138         else
139                 export CLASSPATH=$CLASSBASE:$CLASSPATH
140         fi
143 shift
144 /usr/bin/java $FQCLASS "$@"
145 ====================== Cut here ===================
148 ====================== Cut here ===================
149 /* javaclassname.c
151  * Extracts the class name from a Java class file; intended for use in a Java
152  * wrapper of the type supported by the binfmt_misc option in the Linux kernel.
154  * Copyright (C) 1999 Colin J. Watson <cjw44@cam.ac.uk>.
156  * This program is free software; you can redistribute it and/or modify
157  * it under the terms of the GNU General Public License as published by
158  * the Free Software Foundation; either version 2 of the License, or
159  * (at your option) any later version.
161  * This program is distributed in the hope that it will be useful,
162  * but WITHOUT ANY WARRANTY; without even the implied warranty of
163  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
164  * GNU General Public License for more details.
166  * You should have received a copy of the GNU General Public License
167  * along with this program; if not, write to the Free Software
168  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
169  */
171 #include <stdlib.h>
172 #include <stdio.h>
173 #include <stdarg.h>
174 #include <sys/types.h>
176 /* From Sun's Java VM Specification, as tag entries in the constant pool. */
178 #define CP_UTF8 1
179 #define CP_INTEGER 3
180 #define CP_FLOAT 4
181 #define CP_LONG 5
182 #define CP_DOUBLE 6
183 #define CP_CLASS 7
184 #define CP_STRING 8
185 #define CP_FIELDREF 9
186 #define CP_METHODREF 10
187 #define CP_INTERFACEMETHODREF 11
188 #define CP_NAMEANDTYPE 12
190 /* Define some commonly used error messages */
192 #define seek_error() error("%s: Cannot seek\n", program)
193 #define corrupt_error() error("%s: Class file corrupt\n", program)
194 #define eof_error() error("%s: Unexpected end of file\n", program)
195 #define utf8_error() error("%s: Only ASCII 1-255 supported\n", program);
197 char *program;
199 long *pool;
201 u_int8_t read_8(FILE *classfile);
202 u_int16_t read_16(FILE *classfile);
203 void skip_constant(FILE *classfile, u_int16_t *cur);
204 void error(const char *format, ...);
205 int main(int argc, char **argv);
207 /* Reads in an unsigned 8-bit integer. */
208 u_int8_t read_8(FILE *classfile)
210         int b = fgetc(classfile);
211         if(b == EOF)
212                 eof_error();
213         return (u_int8_t)b;
216 /* Reads in an unsigned 16-bit integer. */
217 u_int16_t read_16(FILE *classfile)
219         int b1, b2;
220         b1 = fgetc(classfile);
221         if(b1 == EOF)
222                 eof_error();
223         b2 = fgetc(classfile);
224         if(b2 == EOF)
225                 eof_error();
226         return (u_int16_t)((b1 << 8) | b2);
229 /* Reads in a value from the constant pool. */
230 void skip_constant(FILE *classfile, u_int16_t *cur)
232         u_int16_t len;
233         int seekerr = 1;
234         pool[*cur] = ftell(classfile);
235         switch(read_8(classfile))
236         {
237         case CP_UTF8:
238                 len = read_16(classfile);
239                 seekerr = fseek(classfile, len, SEEK_CUR);
240                 break;
241         case CP_CLASS:
242         case CP_STRING:
243                 seekerr = fseek(classfile, 2, SEEK_CUR);
244                 break;
245         case CP_INTEGER:
246         case CP_FLOAT:
247         case CP_FIELDREF:
248         case CP_METHODREF:
249         case CP_INTERFACEMETHODREF:
250         case CP_NAMEANDTYPE:
251                 seekerr = fseek(classfile, 4, SEEK_CUR);
252                 break;
253         case CP_LONG:
254         case CP_DOUBLE:
255                 seekerr = fseek(classfile, 8, SEEK_CUR);
256                 ++(*cur);
257                 break;
258         default:
259                 corrupt_error();
260         }
261         if(seekerr)
262                 seek_error();
265 void error(const char *format, ...)
267         va_list ap;
268         va_start(ap, format);
269         vfprintf(stderr, format, ap);
270         va_end(ap);
271         exit(1);
274 int main(int argc, char **argv)
276         FILE *classfile;
277         u_int16_t cp_count, i, this_class, classinfo_ptr;
278         u_int8_t length;
280         program = argv[0];
282         if(!argv[1])
283                 error("%s: Missing input file\n", program);
284         classfile = fopen(argv[1], "rb");
285         if(!classfile)
286                 error("%s: Error opening %s\n", program, argv[1]);
288         if(fseek(classfile, 8, SEEK_SET))  /* skip magic and version numbers */
289                 seek_error();
290         cp_count = read_16(classfile);
291         pool = calloc(cp_count, sizeof(long));
292         if(!pool)
293                 error("%s: Out of memory for constant pool\n", program);
295         for(i = 1; i < cp_count; ++i)
296                 skip_constant(classfile, &i);
297         if(fseek(classfile, 2, SEEK_CUR))       /* skip access flags */
298                 seek_error();
300         this_class = read_16(classfile);
301         if(this_class < 1 || this_class >= cp_count)
302                 corrupt_error();
303         if(!pool[this_class] || pool[this_class] == -1)
304                 corrupt_error();
305         if(fseek(classfile, pool[this_class] + 1, SEEK_SET))
306                 seek_error();
308         classinfo_ptr = read_16(classfile);
309         if(classinfo_ptr < 1 || classinfo_ptr >= cp_count)
310                 corrupt_error();
311         if(!pool[classinfo_ptr] || pool[classinfo_ptr] == -1)
312                 corrupt_error();
313         if(fseek(classfile, pool[classinfo_ptr] + 1, SEEK_SET))
314                 seek_error();
316         length = read_16(classfile);
317         for(i = 0; i < length; ++i)
318         {
319                 u_int8_t x = read_8(classfile);
320                 if((x & 0x80) || !x)
321                 {
322                         if((x & 0xE0) == 0xC0)
323                         {
324                                 u_int8_t y = read_8(classfile);
325                                 if((y & 0xC0) == 0x80)
326                                 {
327                                         int c = ((x & 0x1f) << 6) + (y & 0x3f);
328                                         if(c) putchar(c);
329                                         else utf8_error();
330                                 }
331                                 else utf8_error();
332                         }
333                         else utf8_error();
334                 }
335                 else if(x == '/') putchar('.');
336                 else putchar(x);
337         }
338         putchar('\n');
339         free(pool);
340         fclose(classfile);
341         return 0;
343 ====================== Cut here ===================
346 Now simply chmod +x the .class and/or .html files you want to execute.
347 To add a Java program to your path best put a symbolic link to the main
348 .class file into /usr/bin (or another place you like) omitting the .class
349 extension. The directory containing the original .class file will be
350 added to your CLASSPATH during execution.
353 To test your new setup, enter in the following simple Java app, and name
354 it "HelloWorld.java":
356         class HelloWorld {
357                 public static void main(String args[]) {
358                         System.out.println("Hello World!");
359                 }
360         }
362 Now compile the application with:
363         javac HelloWorld.java
365 Set the executable permissions of the binary file, with:
366         chmod 755 HelloWorld.class
368 And then execute it:
369         ./HelloWorld.class
372 To execute Java Applets, simple chmod the *.html files to include
373 the execution bit, then just do
374         ./Applet.html
377 originally by Brian A. Lantz, brian@lantz.com
378 heavily edited for binfmt_misc by Richard Günther
379 new scripts by Colin J. Watson <cjw44@cam.ac.uk>.