About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / admin-guide / java.rst




Custom Search

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

Information is copyright its respective author. All material is available from the Linux Kernel Source distributed under a GPL License. This page is provided as a free service by mjmwired.net.