Merge tag 'sound-4.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[linux-2.6-block.git] / Documentation / java.txt
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    cannot 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 course you have to fix the path names. The path/file names given 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 #define CP_METHODHANDLE 15
192 #define CP_METHODTYPE 16
193 #define CP_INVOKEDYNAMIC 18
194
195 /* Define some commonly used error messages */
196
197 #define seek_error() error("%s: Cannot seek\n", program)
198 #define corrupt_error() error("%s: Class file corrupt\n", program)
199 #define eof_error() error("%s: Unexpected end of file\n", program)
200 #define utf8_error() error("%s: Only ASCII 1-255 supported\n", program);
201
202 char *program;
203
204 long *pool;
205
206 u_int8_t read_8(FILE *classfile);
207 u_int16_t read_16(FILE *classfile);
208 void skip_constant(FILE *classfile, u_int16_t *cur);
209 void error(const char *format, ...);
210 int main(int argc, char **argv);
211
212 /* Reads in an unsigned 8-bit integer. */
213 u_int8_t read_8(FILE *classfile)
214 {
215         int b = fgetc(classfile);
216         if(b == EOF)
217                 eof_error();
218         return (u_int8_t)b;
219 }
220
221 /* Reads in an unsigned 16-bit integer. */
222 u_int16_t read_16(FILE *classfile)
223 {
224         int b1, b2;
225         b1 = fgetc(classfile);
226         if(b1 == EOF)
227                 eof_error();
228         b2 = fgetc(classfile);
229         if(b2 == EOF)
230                 eof_error();
231         return (u_int16_t)((b1 << 8) | b2);
232 }
233
234 /* Reads in a value from the constant pool. */
235 void skip_constant(FILE *classfile, u_int16_t *cur)
236 {
237         u_int16_t len;
238         int seekerr = 1;
239         pool[*cur] = ftell(classfile);
240         switch(read_8(classfile))
241         {
242         case CP_UTF8:
243                 len = read_16(classfile);
244                 seekerr = fseek(classfile, len, SEEK_CUR);
245                 break;
246         case CP_CLASS:
247         case CP_STRING:
248         case CP_METHODTYPE:
249                 seekerr = fseek(classfile, 2, SEEK_CUR);
250                 break;
251         case CP_METHODHANDLE:
252                 seekerr = fseek(classfile, 3, SEEK_CUR);
253                 break;
254         case CP_INTEGER:
255         case CP_FLOAT:
256         case CP_FIELDREF:
257         case CP_METHODREF:
258         case CP_INTERFACEMETHODREF:
259         case CP_NAMEANDTYPE:
260         case CP_INVOKEDYNAMIC:
261                 seekerr = fseek(classfile, 4, SEEK_CUR);
262                 break;
263         case CP_LONG:
264         case CP_DOUBLE:
265                 seekerr = fseek(classfile, 8, SEEK_CUR);
266                 ++(*cur);
267                 break;
268         default:
269                 corrupt_error();
270         }
271         if(seekerr)
272                 seek_error();
273 }
274
275 void error(const char *format, ...)
276 {
277         va_list ap;
278         va_start(ap, format);
279         vfprintf(stderr, format, ap);
280         va_end(ap);
281         exit(1);
282 }
283
284 int main(int argc, char **argv)
285 {
286         FILE *classfile;
287         u_int16_t cp_count, i, this_class, classinfo_ptr;
288         u_int8_t length;
289
290         program = argv[0];
291
292         if(!argv[1])
293                 error("%s: Missing input file\n", program);
294         classfile = fopen(argv[1], "rb");
295         if(!classfile)
296                 error("%s: Error opening %s\n", program, argv[1]);
297
298         if(fseek(classfile, 8, SEEK_SET))  /* skip magic and version numbers */
299                 seek_error();
300         cp_count = read_16(classfile);
301         pool = calloc(cp_count, sizeof(long));
302         if(!pool)
303                 error("%s: Out of memory for constant pool\n", program);
304
305         for(i = 1; i < cp_count; ++i)
306                 skip_constant(classfile, &i);
307         if(fseek(classfile, 2, SEEK_CUR))       /* skip access flags */
308                 seek_error();
309
310         this_class = read_16(classfile);
311         if(this_class < 1 || this_class >= cp_count)
312                 corrupt_error();
313         if(!pool[this_class] || pool[this_class] == -1)
314                 corrupt_error();
315         if(fseek(classfile, pool[this_class] + 1, SEEK_SET))
316                 seek_error();
317
318         classinfo_ptr = read_16(classfile);
319         if(classinfo_ptr < 1 || classinfo_ptr >= cp_count)
320                 corrupt_error();
321         if(!pool[classinfo_ptr] || pool[classinfo_ptr] == -1)
322                 corrupt_error();
323         if(fseek(classfile, pool[classinfo_ptr] + 1, SEEK_SET))
324                 seek_error();
325
326         length = read_16(classfile);
327         for(i = 0; i < length; ++i)
328         {
329                 u_int8_t x = read_8(classfile);
330                 if((x & 0x80) || !x)
331                 {
332                         if((x & 0xE0) == 0xC0)
333                         {
334                                 u_int8_t y = read_8(classfile);
335                                 if((y & 0xC0) == 0x80)
336                                 {
337                                         int c = ((x & 0x1f) << 6) + (y & 0x3f);
338                                         if(c) putchar(c);
339                                         else utf8_error();
340                                 }
341                                 else utf8_error();
342                         }
343                         else utf8_error();
344                 }
345                 else if(x == '/') putchar('.');
346                 else putchar(x);
347         }
348         putchar('\n');
349         free(pool);
350         fclose(classfile);
351         return 0;
352 }
353 ====================== Cut here ===================
354
355
356 ====================== Cut here ===================
357 #!/bin/bash
358 # /usr/local/java/bin/jarwrapper - the wrapper for binfmt_misc/jar
359
360 java -jar $1
361 ====================== Cut here ===================
362
363
364 Now simply chmod +x the .class, .jar and/or .html files you want to execute.
365 To add a Java program to your path best put a symbolic link to the main
366 .class file into /usr/bin (or another place you like) omitting the .class
367 extension. The directory containing the original .class file will be
368 added to your CLASSPATH during execution.
369
370
371 To test your new setup, enter in the following simple Java app, and name
372 it "HelloWorld.java":
373
374         class HelloWorld {
375                 public static void main(String args[]) {
376                         System.out.println("Hello World!");
377                 }
378         }
379
380 Now compile the application with:
381         javac HelloWorld.java
382
383 Set the executable permissions of the binary file, with:
384         chmod 755 HelloWorld.class
385
386 And then execute it:
387         ./HelloWorld.class
388
389
390 To execute Java Jar files, simple chmod the *.jar files to include
391 the execution bit, then just do
392        ./Application.jar
393
394
395 To execute Java Applets, simple chmod the *.html files to include
396 the execution bit, then just do
397         ./Applet.html
398
399
400 originally by Brian A. Lantz, brian@lantz.com
401 heavily edited for binfmt_misc by Richard Günther
402 new scripts by Colin J. Watson <cjw44@cam.ac.uk>
403 added executable Jar file support by Kurt Huwig <kurt@iku-netz.de>
404