About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / java.txt


Based on kernel version 4.9. Page generated on 2016-12-21 14:34 EST.

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>
Hide Line Numbers


About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog