mirror of
https://github.com/corda/corda.git
synced 2025-01-01 02:36:44 +00:00
enable standalone OpenJDK builds
As described in readme.txt, a standalone OpenJDK build embeds all libraries, classes, and other files needed at runtime in the resulting binary, eliminating dependencies on external resources.
This commit is contained in:
parent
cb69ac23bd
commit
cabad6926f
110
makefile
110
makefile
@ -52,22 +52,31 @@ classpath = avian
|
||||
|
||||
test-executable = $(executable)
|
||||
boot-classpath = $(classpath-build)
|
||||
java-home = /tmp
|
||||
java-home = /avian-embedded
|
||||
|
||||
ifdef openjdk
|
||||
ifdef openjdk-src
|
||||
include openjdk-src.mk
|
||||
options := $(options)-openjdk-src
|
||||
classpath-objects = $(openjdk-objects)
|
||||
classpath-cflags = -DAVIAN_OPENJDK_SRC
|
||||
openjdk-jar-dep = $(build)/openjdk-jar.dep
|
||||
classpath-jar-dep = $(openjdk-jar-dep)
|
||||
else
|
||||
options := $(options)-openjdk
|
||||
test-executable = $(executable-dynamic)
|
||||
library-path = LD_LIBRARY_PATH=$(build)
|
||||
java-home = $(openjdk)/jre
|
||||
endif
|
||||
|
||||
classpath = openjdk
|
||||
options := $(options)-openjdk
|
||||
java-home = $(openjdk)/jre
|
||||
test-executable = $(executable-dynamic)
|
||||
boot-classpath := $(boot-classpath):$(openjdk)/jre/lib/rt.jar
|
||||
endif
|
||||
|
||||
ifneq ($(classpath),avian)
|
||||
classpath-object-dep = $(build)/classpath-object.dep
|
||||
classpath-objects = $(shell find $(build)/classpath-objects -name "*.o")
|
||||
else
|
||||
ifeq ($(classpath),avian)
|
||||
jni-sources := $(shell find $(classpath-src) -name '*.cpp')
|
||||
jni-objects = $(call cpp-objects,$(jni-sources),$(classpath-src),$(build))
|
||||
classpath-objects = $(jni-objects)
|
||||
endif
|
||||
|
||||
input = List
|
||||
@ -95,6 +104,7 @@ vg = nice valgrind --num-callers=32 --db-attach=yes --freelist-vol=100000000
|
||||
vg += --leak-check=full --suppressions=valgrind.supp
|
||||
db = gdb --args
|
||||
javac = "$(JAVA_HOME)/bin/javac"
|
||||
javah = "$(JAVA_HOME)/bin/javah"
|
||||
jar = "$(JAVA_HOME)/bin/jar"
|
||||
strip = strip
|
||||
strip-all = --strip-all
|
||||
@ -108,7 +118,7 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
|
||||
-Wno-non-virtual-dtor
|
||||
|
||||
common-cflags = $(warnings) -fno-rtti -fno-exceptions -fno-omit-frame-pointer \
|
||||
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) \
|
||||
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \
|
||||
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
||||
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(java-home)\"
|
||||
|
||||
@ -222,28 +232,30 @@ ifeq ($(platform),windows)
|
||||
endif
|
||||
|
||||
ifeq ($(mode),debug)
|
||||
cflags += -O0 -g3
|
||||
optimization-cflags = -O0 -g3
|
||||
strip = :
|
||||
endif
|
||||
ifeq ($(mode),debug-fast)
|
||||
cflags += -O0 -g3 -DNDEBUG
|
||||
optimization-cflags = -O0 -g3 -DNDEBUG
|
||||
strip = :
|
||||
endif
|
||||
ifeq ($(mode),stress)
|
||||
cflags += -O0 -g3 -DVM_STRESS
|
||||
optimization-cflags = -O0 -g3 -DVM_STRESS
|
||||
strip = :
|
||||
endif
|
||||
ifeq ($(mode),stress-major)
|
||||
cflags += -O0 -g3 -DVM_STRESS -DVM_STRESS_MAJOR
|
||||
optimization-cflags = -O0 -g3 -DVM_STRESS -DVM_STRESS_MAJOR
|
||||
strip = :
|
||||
endif
|
||||
ifeq ($(mode),fast)
|
||||
cflags += -O3 -g3 -DNDEBUG
|
||||
optimization-cflags = -O3 -g3 -DNDEBUG
|
||||
endif
|
||||
ifeq ($(mode),small)
|
||||
cflags += -Os -g3 -DNDEBUG
|
||||
optimization-cflags = -Os -g3 -DNDEBUG
|
||||
endif
|
||||
|
||||
cflags += $(optimization-cflags)
|
||||
|
||||
ifneq ($(platform),darwin)
|
||||
ifeq ($(arch),i386)
|
||||
# this is necessary to support __sync_bool_compare_and_swap:
|
||||
@ -467,15 +479,15 @@ $(test-extra-dep): $(classpath-dep)
|
||||
|
||||
.PHONY: run
|
||||
run: build
|
||||
LD_LIBRARY_PATH=$(build) $(test-executable) $(test-args)
|
||||
$(library-path) $(test-executable) $(test-args)
|
||||
|
||||
.PHONY: debug
|
||||
debug: build
|
||||
LD_LIBRARY_PATH=$(build) gdb --args $(test-executable) $(test-args)
|
||||
$(library-path) gdb --args $(test-executable) $(test-args)
|
||||
|
||||
.PHONY: vg
|
||||
vg: build
|
||||
LD_LIBRARY_PATH=$(build) $(vg) $(test-executable) $(test-args)
|
||||
$(library-path) $(vg) $(test-executable) $(test-args)
|
||||
|
||||
.PHONY: test
|
||||
test: build
|
||||
@ -581,7 +593,8 @@ $(driver-dynamic-object): $(driver-source)
|
||||
$(boot-object): $(boot-source)
|
||||
$(compile-object)
|
||||
|
||||
$(build)/classpath.jar: $(classpath-dep)
|
||||
$(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep)
|
||||
@echo "creating $(@)"
|
||||
(wd=$$(pwd) && \
|
||||
cd $(classpath-build) && \
|
||||
$(jar) c0f "$$($(native-path) "$${wd}/$(@)")" .)
|
||||
@ -622,11 +635,10 @@ $(generator-objects): $(build)/%-build.o: $(src)/%.cpp
|
||||
$(jni-objects): $(build)/%.o: $(classpath-src)/%.cpp
|
||||
$(compile-object)
|
||||
|
||||
$(static-library): $(classpath-object-dep)
|
||||
$(static-library): $(vm-objects) $(jni-objects) $(vm-heapwalk-objects)
|
||||
$(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects)
|
||||
@echo "creating $(@)"
|
||||
rm -rf $(@)
|
||||
$(ar) cru $(@) $(^) $(call classpath-objects)
|
||||
$(ar) cru $(@) $(^)
|
||||
$(ranlib) $(@)
|
||||
|
||||
$(bootimage-bin): $(bootimage-generator)
|
||||
@ -638,16 +650,10 @@ $(bootimage-object): $(bootimage-bin) $(converter)
|
||||
_binary_bootimage_bin_end $(platform) $(arch) $(pointer-size) \
|
||||
writable executable
|
||||
|
||||
$(classpath-object-dep): $(classpath-libraries)
|
||||
@mkdir -p $(build)/classpath-objects
|
||||
(cd $(build)/classpath-objects && \
|
||||
for x in $(classpath-libraries); do ar x $${x}; done)
|
||||
@touch $(@)
|
||||
|
||||
executable-objects = $(vm-objects) $(jni-objects) $(driver-object) \
|
||||
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
|
||||
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-object)
|
||||
|
||||
$(executable): $(classpath-object-dep) $(executable-objects)
|
||||
$(executable): $(executable-objects)
|
||||
@echo "linking $(@)"
|
||||
ifeq ($(platform),windows)
|
||||
ifdef msvc
|
||||
@ -655,14 +661,12 @@ ifdef msvc
|
||||
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest
|
||||
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
|
||||
else
|
||||
$(dlltool) -z $(@).def $(executable-objects) $(call classpath-objects)
|
||||
$(dlltool) -z $(@).def $(executable-objects)
|
||||
$(dlltool) -d $(@).def -e $(@).exp
|
||||
$(ld) $(@).exp $(executable-objects) $(call classpath-objects) $(lflags) \
|
||||
-o $(@)
|
||||
$(ld) $(@).exp $(executable-objects) $(lflags) -o $(@)
|
||||
endif
|
||||
else
|
||||
$(ld) $(executable-objects) $(call classpath-objects) $(rdynamic) $(lflags) \
|
||||
$(bootimage-lflags) -o $(@)
|
||||
$(ld) $(executable-objects) $(rdynamic) $(lflags) $(bootimage-lflags) -o $(@)
|
||||
endif
|
||||
$(strip) $(strip-all) $(@)
|
||||
|
||||
@ -675,8 +679,8 @@ $(bootimage-generator):
|
||||
$(bootimage-generator)
|
||||
|
||||
$(build-bootimage-generator): \
|
||||
$(vm-objects) $(classpath-object) $(jni-objects) $(heapwalk-objects) \
|
||||
$(bootimage-generator-objects)
|
||||
$(vm-objects) $(classpath-object) $(classpath-objects) \
|
||||
$(heapwalk-objects) $(bootimage-generator-objects)
|
||||
@echo "linking $(@)"
|
||||
ifeq ($(platform),windows)
|
||||
ifdef msvc
|
||||
@ -692,11 +696,11 @@ else
|
||||
$(ld) $(^) $(rdynamic) $(lflags) -o $(@)
|
||||
endif
|
||||
|
||||
dynamic-library-objects = $(vm-objects) $(dynamic-object) $(jni-objects) \
|
||||
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-object) \
|
||||
$(classpath-libraries)
|
||||
dynamic-library-objects = $(vm-objects) $(dynamic-object) \
|
||||
$(classpath-objects) $(vm-heapwalk-objects) $(boot-object) \
|
||||
$(vm-classpath-object) $(classpath-libraries)
|
||||
|
||||
$(dynamic-library): $(classpath-object-dep) $(dynamic-library-objects)
|
||||
$(dynamic-library): $(dynamic-library-objects)
|
||||
@echo "linking $(@)"
|
||||
ifdef msvc
|
||||
$(ld) $(shared) $(lflags) $(dynamic-library-objects) -out:$(@) \
|
||||
@ -704,7 +708,7 @@ ifdef msvc
|
||||
$(mt) -manifest $(@).manifest -outputresource:"$(@);2"
|
||||
else
|
||||
$(ld) $(dynamic-library-objects) -Wl,--version-script=openjdk.ld \
|
||||
$(call classpath-objects) $(shared) $(lflags) $(bootimage-lflags) -o $(@)
|
||||
$(shared) $(lflags) $(bootimage-lflags) -o $(@)
|
||||
endif
|
||||
$(strip) $(strip-all) $(@)
|
||||
|
||||
@ -722,3 +726,25 @@ endif
|
||||
$(generator): $(generator-objects)
|
||||
@echo "linking $(@)"
|
||||
$(build-ld) $(^) $(build-lflags) -o $(@)
|
||||
|
||||
$(openjdk-objects): $(build)/openjdk/%.o: $(openjdk-src)/%.c \
|
||||
$(openjdk-headers-dep)
|
||||
@echo "compiling $(@)"
|
||||
@mkdir -p $(dir $(@))
|
||||
$(cc) -fPIC -fvisibility=hidden $(openjdk-cflags) $(optimization-cflags) \
|
||||
-w -c $(<) $(call output,$(@))
|
||||
|
||||
$(openjdk-headers-dep): $(openjdk)/jre/lib/rt.jar
|
||||
@echo "generating openjdk headers"
|
||||
@mkdir -p $(dir $(@))
|
||||
$(javah) -d $(build)/openjdk -bootclasspath $(boot-classpath) \
|
||||
$(openjdk-headers-classes)
|
||||
@touch $(@)
|
||||
|
||||
$(openjdk-jar-dep): $(openjdk)/jre/lib/rt.jar $(openjdk)/jre/lib/jsse.jar \
|
||||
$(openjdk)/jre/lib/jce.jar $(openjdk)/jre/lib/resources.jar
|
||||
@echo "extracting openjdk classes"
|
||||
@mkdir -p $(dir $(@))
|
||||
@mkdir -p $(classpath-build)
|
||||
(cd $(classpath-build) && for x in $(^); do jar xf $${x}; done)
|
||||
@touch $(@)
|
||||
|
166
openjdk-src.mk
Normal file
166
openjdk-src.mk
Normal file
@ -0,0 +1,166 @@
|
||||
openjdk-sources = \
|
||||
$(openjdk-src)/share/native/common/check_code.c \
|
||||
$(openjdk-src)/share/native/common/check_format.c \
|
||||
$(openjdk-src)/share/native/common/check_version.c \
|
||||
$(openjdk-src)/share/native/common/jdk_util.c \
|
||||
$(openjdk-src)/share/native/common/jio.c \
|
||||
$(openjdk-src)/share/native/common/jni_util.c \
|
||||
$(openjdk-src)/share/native/common/verify_stub.c \
|
||||
$(openjdk-src)/share/native/java/io/FileInputStream.c \
|
||||
$(openjdk-src)/share/native/java/io/io_util.c \
|
||||
$(openjdk-src)/share/native/java/io/ObjectInputStream.c \
|
||||
$(openjdk-src)/share/native/java/io/ObjectOutputStream.c \
|
||||
$(openjdk-src)/share/native/java/io/ObjectStreamClass.c \
|
||||
$(openjdk-src)/share/native/java/io/RandomAccessFile.c \
|
||||
$(openjdk-src)/share/native/java/lang/Class.c \
|
||||
$(openjdk-src)/share/native/java/lang/ClassLoader.c \
|
||||
$(openjdk-src)/share/native/java/lang/Compiler.c \
|
||||
$(openjdk-src)/share/native/java/lang/Double.c \
|
||||
$(openjdk-src)/share/native/java/lang/Float.c \
|
||||
$(openjdk-src)/share/native/java/lang/Object.c \
|
||||
$(openjdk-src)/share/native/java/lang/Package.c \
|
||||
$(openjdk-src)/share/native/java/lang/ref/Finalizer.c \
|
||||
$(openjdk-src)/share/native/java/lang/reflect/Array.c \
|
||||
$(openjdk-src)/share/native/java/lang/reflect/Proxy.c \
|
||||
$(openjdk-src)/share/native/java/lang/ResourceBundle.c \
|
||||
$(openjdk-src)/share/native/java/lang/Runtime.c \
|
||||
$(openjdk-src)/share/native/java/lang/SecurityManager.c \
|
||||
$(openjdk-src)/share/native/java/lang/Shutdown.c \
|
||||
$(openjdk-src)/share/native/java/lang/StrictMath.c \
|
||||
$(openjdk-src)/share/native/java/lang/String.c \
|
||||
$(openjdk-src)/share/native/java/lang/System.c \
|
||||
$(openjdk-src)/share/native/java/lang/Thread.c \
|
||||
$(openjdk-src)/share/native/java/lang/Throwable.c \
|
||||
$(wildcard $(openjdk-src)/share/native/java/lang/fdlibm/src/*.c) \
|
||||
$(openjdk-src)/share/native/java/nio/Bits.c \
|
||||
$(openjdk-src)/share/native/java/security/AccessController.c \
|
||||
$(openjdk-src)/share/native/java/sql/DriverManager.c \
|
||||
$(openjdk-src)/share/native/java/util/concurrent/atomic/AtomicLong.c \
|
||||
$(openjdk-src)/share/native/java/util/TimeZone.c \
|
||||
$(openjdk-src)/share/native/java/util/zip/Adler32.c \
|
||||
$(openjdk-src)/share/native/java/util/zip/CRC32.c \
|
||||
$(openjdk-src)/share/native/java/util/zip/Deflater.c \
|
||||
$(openjdk-src)/share/native/java/util/zip/Inflater.c \
|
||||
$(openjdk-src)/share/native/java/util/zip/ZipEntry.c \
|
||||
$(openjdk-src)/share/native/java/util/zip/ZipFile.c \
|
||||
$(openjdk-src)/share/native/java/util/zip/zip_util.c \
|
||||
$(openjdk-src)/share/native/sun/misc/GC.c \
|
||||
$(openjdk-src)/share/native/sun/misc/MessageUtils.c \
|
||||
$(openjdk-src)/share/native/sun/misc/NativeSignalHandler.c \
|
||||
$(openjdk-src)/share/native/sun/misc/Signal.c \
|
||||
$(openjdk-src)/share/native/sun/misc/Version.c \
|
||||
$(openjdk-src)/share/native/sun/misc/VM.c \
|
||||
$(openjdk-src)/share/native/sun/misc/VMSupport.c \
|
||||
$(openjdk-src)/share/native/sun/reflect/ConstantPool.c \
|
||||
$(openjdk-src)/share/native/sun/reflect/NativeAccessors.c \
|
||||
$(openjdk-src)/share/native/sun/reflect/Reflection.c
|
||||
|
||||
openjdk-headers-classes = \
|
||||
java.io.Console \
|
||||
java.io.FileDescriptor \
|
||||
java.io.FileInputStream \
|
||||
java.io.FileOutputStream \
|
||||
java.io.FileSystem \
|
||||
java.io.ObjectInputStream \
|
||||
java.io.ObjectOutputStream \
|
||||
java.io.ObjectStreamClass \
|
||||
java.io.RandomAccessFile \
|
||||
java.lang.Class \
|
||||
java.lang.ClassLoader \
|
||||
java.lang.Compiler \
|
||||
java.lang.Double \
|
||||
java.lang.Float \
|
||||
java.lang.Object \
|
||||
java.lang.Package \
|
||||
java.lang.Runtime \
|
||||
java.lang.SecurityManager \
|
||||
java.lang.Shutdown \
|
||||
java.lang.StrictMath \
|
||||
java.lang.String \
|
||||
java.lang.System \
|
||||
java.lang.Thread \
|
||||
java.lang.Throwable \
|
||||
java.lang.ref.Finalizer \
|
||||
java.lang.reflect.Array \
|
||||
java.lang.reflect.Proxy \
|
||||
java.security.AccessController \
|
||||
java.util.ResourceBundle \
|
||||
java.util.TimeZone \
|
||||
java.util.concurrent.atomic.AtomicLong \
|
||||
java.util.jar.JarFile \
|
||||
java.util.zip.Adler32 \
|
||||
java.util.zip.CRC32 \
|
||||
java.util.zip.Deflater \
|
||||
java.util.zip.Inflater \
|
||||
java.util.zip.ZipEntry \
|
||||
java.util.zip.ZipFile \
|
||||
sun.misc.GC \
|
||||
sun.misc.MessageUtils \
|
||||
sun.misc.NativeSignalHandler \
|
||||
sun.misc.Signal \
|
||||
sun.misc.VM \
|
||||
sun.misc.VMSupport \
|
||||
sun.misc.Version \
|
||||
sun.reflect.ConstantPool \
|
||||
sun.reflect.NativeConstructorAccessorImpl \
|
||||
sun.reflect.NativeMethodAccessorImpl \
|
||||
sun.reflect.Reflection \
|
||||
|
||||
# todo: set properties according to architecture targeted and OpenJDK
|
||||
# version used:
|
||||
openjdk-cflags = \
|
||||
"-I$(src)/openjdk" \
|
||||
"-I$(build)/openjdk" \
|
||||
"-I$(openjdk-src)/share/javavm/export" \
|
||||
"-I$(openjdk-src)/share/native/common" \
|
||||
"-I$(openjdk-src)/share/native/java/io" \
|
||||
"-I$(openjdk-src)/share/native/java/lang" \
|
||||
"-I$(openjdk-src)/share/native/java/lang/fdlibm/include" \
|
||||
"-I$(openjdk-src)/share/native/java/util/zip" \
|
||||
"-I$(openjdk-src)/share/javavm/include" \
|
||||
-D_LITTLE_ENDIAN \
|
||||
-DARCHPROPNAME=\"x86\" \
|
||||
-DRELEASE=\"1.6.0\" \
|
||||
-DJDK_MAJOR_VERSION=\"1\" \
|
||||
-DJDK_MINOR_VERSION=\"6\" \
|
||||
-DJDK_MICRO_VERSION=\"0\" \
|
||||
-DJDK_BUILD_NUMBER=\"0\" \
|
||||
-D_GNU_SOURCE
|
||||
|
||||
ifeq ($(platform),windows)
|
||||
# todo
|
||||
else
|
||||
openjdk-sources += \
|
||||
$(openjdk-src)/solaris/native/common/jdk_util_md.c \
|
||||
$(openjdk-src)/solaris/native/java/io/canonicalize_md.c \
|
||||
$(openjdk-src)/solaris/native/java/io/Console_md.c \
|
||||
$(openjdk-src)/solaris/native/java/io/FileDescriptor_md.c \
|
||||
$(openjdk-src)/solaris/native/java/io/FileInputStream_md.c \
|
||||
$(openjdk-src)/solaris/native/java/io/FileOutputStream_md.c \
|
||||
$(openjdk-src)/solaris/native/java/io/FileSystem_md.c \
|
||||
$(openjdk-src)/solaris/native/java/io/io_util_md.c \
|
||||
$(openjdk-src)/solaris/native/java/io/RandomAccessFile_md.c \
|
||||
$(openjdk-src)/solaris/native/java/io/UnixFileSystem_md.c \
|
||||
$(openjdk-src)/solaris/native/java/lang/java_props_md.c \
|
||||
$(openjdk-src)/solaris/native/java/lang/ProcessEnvironment_md.c \
|
||||
$(openjdk-src)/solaris/native/java/lang/UNIXProcess_md.c \
|
||||
$(openjdk-src)/solaris/native/java/util/FileSystemPreferences.c \
|
||||
$(openjdk-src)/solaris/native/java/util/logging.c \
|
||||
$(openjdk-src)/solaris/native/java/util/TimeZone_md.c
|
||||
|
||||
openjdk-headers-classes += \
|
||||
java.io.UnixFileSystem
|
||||
|
||||
openjdk-cflags += "-I$(openjdk-src)/solaris/javavm/export" \
|
||||
"-I$(openjdk-src)/solaris/native/common" \
|
||||
"-I$(openjdk-src)/solaris/native/java/io" \
|
||||
"-I$(openjdk-src)/solaris/native/java/util" \
|
||||
"-I$(openjdk-src)/solaris/javavm/include"
|
||||
endif
|
||||
|
||||
c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%.o,$(x)))
|
||||
|
||||
openjdk-objects = \
|
||||
$(call c-objects,$(openjdk-sources),$(openjdk-src),$(build)/openjdk)
|
||||
|
||||
openjdk-headers-dep = $(build)/openjdk/headers.dep
|
48
readme.txt
48
readme.txt
@ -191,6 +191,54 @@ Finally, build with the msvc flag set to the MSVC tool directory:
|
||||
$ make msvc="/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/VC"
|
||||
|
||||
|
||||
Building with the OpenJDK Class Library
|
||||
---------------------------------------
|
||||
|
||||
By default, Avian uses its own lightweight class library. However,
|
||||
that library only contains a relatively small subset of the classes
|
||||
and methods included in the JRE. If your application requires
|
||||
features beyond that subset, you may want to tell Avian to use
|
||||
OpenJDK's class library instead. To do so, specify the directory
|
||||
where OpenJDK is installed, e.g.:
|
||||
|
||||
$ make openjdk=/usr/lib/jvm/java-6-openjdk
|
||||
|
||||
This will build Avian as a conventional JVM (e.g. libjvm.so) which
|
||||
loads its boot class library and native libraries (e.g. libjava.so)
|
||||
from /usr/lib/jvm/java-6-openjdk/jre at runtime. To run an
|
||||
application in this configuration, you'll need to make sure the VM is
|
||||
in your library search path. For example:
|
||||
|
||||
$ LD_LIBRARY_PATH=build/linux-x86_64-openjdk \
|
||||
build/linux-x86_64-openjdk/avian-dynamic -cp /path/to/my/application \
|
||||
com.example.MyApplication
|
||||
|
||||
Alternatively, you can enable a stand-alone build using OpenJDK by
|
||||
specifying the location of the OpenJDK source code, e.g.:
|
||||
|
||||
$ make openjdk=$(pwd)/../jdk6/build/linux-amd64/j2sdk-image \
|
||||
openjdk-src=$(pwd)/../jdk6/jdk/src
|
||||
|
||||
The result of such a build is a self-contained binary which does not
|
||||
depend on external libraries, jars, or other files. In this case, the
|
||||
specified paths are used only at build time; anything needed at
|
||||
runtime is embedded in the binary. Thus, the process of running an
|
||||
application is simplified:
|
||||
|
||||
$ build/linux-x86_64-openjdk-src/avian -cp /path/to/my/application \
|
||||
com.example.MyApplication
|
||||
|
||||
Note that the resulting binary will be very large due to the size of
|
||||
OpenJDK's class library. This can be mitigated using UPX, preferably
|
||||
an LZMA-enabled version:
|
||||
|
||||
$ upx --lzma --best build/linux-x86_64-openjdk-src/avian
|
||||
|
||||
You can reduce the size futher for embedded builds by using ProGuard
|
||||
and the supplied openjdk.pro configuration file (see "Embedding with
|
||||
ProGuard and a Boot Image" below).
|
||||
|
||||
|
||||
Installing
|
||||
----------
|
||||
|
||||
|
@ -35,6 +35,9 @@
|
||||
# define CREAT _wcreat
|
||||
# endif
|
||||
|
||||
# define LIBRARY_PREFIX ""
|
||||
# define LIBRARY_SUFFIX ".dll"
|
||||
|
||||
#else // not PLATFORM_WINDOWS
|
||||
|
||||
# include <unistd.h>
|
||||
@ -53,6 +56,9 @@
|
||||
# define FSTAT fstat
|
||||
# define LSEEK lseek
|
||||
|
||||
# define LIBRARY_PREFIX "lib"
|
||||
# define LIBRARY_SUFFIX ".so"
|
||||
|
||||
#endif // not PLATFORM_WINDOWS
|
||||
|
||||
using namespace vm;
|
||||
@ -139,6 +145,72 @@ makeClassNameString(Thread* t, object name)
|
||||
return makeString(t, "%s", s);
|
||||
}
|
||||
|
||||
#ifdef AVIAN_OPENJDK_SRC
|
||||
// only safe to call during bootstrap when there's only one thread
|
||||
// running:
|
||||
void
|
||||
intercept(Thread* t, object c, const char* name, const char* spec,
|
||||
void* function)
|
||||
{
|
||||
object m = findMethodOrNull(t, c, name, spec);
|
||||
if (m) {
|
||||
PROTECT(t, m);
|
||||
|
||||
object clone = methodClone(t, m);
|
||||
|
||||
// make clone private to prevent vtable updates at compilation
|
||||
// time. Otherwise, our interception might be bypassed by calls
|
||||
// through the vtable.
|
||||
methodFlags(t, clone) |= ACC_PRIVATE;
|
||||
|
||||
methodFlags(t, m) |= ACC_NATIVE;
|
||||
|
||||
object native = makeNativeIntercept(t, function, true, clone);
|
||||
|
||||
set(t, m, MethodCode, native);
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
zipLibrary(Thread*);
|
||||
|
||||
int64_t JNICALL
|
||||
getFileAttributes
|
||||
(Thread* t, object method, uintptr_t* arguments)
|
||||
{
|
||||
const unsigned Exists = 1;
|
||||
const unsigned Regular = 2;
|
||||
|
||||
object file = reinterpret_cast<object>(arguments[1]);
|
||||
|
||||
object pathField = findFieldInClass2
|
||||
(t, objectClass(t, file), "path", "Ljava/lang/String;");
|
||||
|
||||
if (pathField) {
|
||||
object path = cast<object>(file, fieldOffset(t, pathField));
|
||||
|
||||
RUNTIME_ARRAY(char, p, stringLength(t, path) + 1);
|
||||
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
||||
|
||||
if (strcmp(zipLibrary(t), p) == 0) {
|
||||
return Exists | Regular;
|
||||
} else {
|
||||
object r = t->m->processor->invoke
|
||||
(t, nativeInterceptOriginal(t, methodCode(t, method)),
|
||||
reinterpret_cast<object>(arguments[0]), file);
|
||||
return (r ? intValue(t, r) : 0);
|
||||
}
|
||||
} else {
|
||||
object message = makeString
|
||||
(t, "path Ljava/lang/String; not found in %s",
|
||||
&byteArrayBody(t, className(t, objectClass(t, file)), 0));
|
||||
t->exception = t->m->classpath->makeThrowable
|
||||
(t, Machine::RuntimeExceptionType, message);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif // AVIAN_OPENJDK_SRC
|
||||
|
||||
class MyClasspath : public Classpath {
|
||||
public:
|
||||
static const unsigned BufferSize = 1024;
|
||||
@ -205,6 +277,14 @@ class MyClasspath : public Classpath {
|
||||
// todo: handle other architectures
|
||||
sb.append("/lib/i386");
|
||||
#endif
|
||||
sb.append('\0');
|
||||
|
||||
this->zipLibrary = sb.pointer;
|
||||
sb.append(this->libraryPath);
|
||||
sb.append("/");
|
||||
sb.append(LIBRARY_PREFIX);
|
||||
sb.append("zip");
|
||||
sb.append(LIBRARY_SUFFIX);
|
||||
}
|
||||
|
||||
virtual object
|
||||
@ -296,9 +376,20 @@ class MyClasspath : public Classpath {
|
||||
{
|
||||
globalMachine = t->m;
|
||||
|
||||
#ifdef AVIAN_OPENJDK_SRC
|
||||
{ object c = resolveClass
|
||||
(t, root(t, Machine::BootLoader), "java/io/UnixFileSystem");
|
||||
|
||||
if (c) {
|
||||
intercept(t, c, "getBooleanAttributes0", "(Ljava/io/File;)I",
|
||||
voidPointer(getFileAttributes));
|
||||
}
|
||||
}
|
||||
#else // not AVIAN_OPENJDK_SRC
|
||||
if (loadLibrary(t, libraryPath, "java", true, true) == 0) {
|
||||
abort(t);
|
||||
}
|
||||
#endif // not AVIAN_OPENJDK_SRC
|
||||
|
||||
t->m->processor->invoke
|
||||
(t, root(t, Machine::BootLoader), "java/lang/System",
|
||||
@ -351,6 +442,7 @@ class MyClasspath : public Classpath {
|
||||
const char* javaHome;
|
||||
const char* classpath;
|
||||
const char* libraryPath;
|
||||
const char* zipLibrary;
|
||||
char buffer[BufferSize];
|
||||
};
|
||||
|
||||
@ -374,6 +466,12 @@ struct jvm_version_info {
|
||||
unsigned int: 32;
|
||||
};
|
||||
|
||||
const char*
|
||||
zipLibrary(Thread* t)
|
||||
{
|
||||
return static_cast<MyClasspath*>(t->m->classpath)->zipLibrary;
|
||||
}
|
||||
|
||||
unsigned
|
||||
countMethods(Thread* t, object c, bool publicOnly)
|
||||
{
|
||||
@ -1205,7 +1303,13 @@ extern "C" JNIEXPORT void* JNICALL
|
||||
JVM_LoadLibrary(const char* name)
|
||||
{
|
||||
Thread* t = static_cast<Thread*>(local::globalMachine->localThread->get());
|
||||
|
||||
|
||||
#ifdef AVIAN_OPENJDK_SRC
|
||||
if (strcmp(local::zipLibrary(t), name) == 0) {
|
||||
return t->m->libraries;
|
||||
}
|
||||
#endif // AVIAN_OPENJDK_SRC
|
||||
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
return loadLibrary
|
||||
@ -2597,18 +2701,18 @@ jio_vsnprintf(char* dst, size_t size, const char* format, va_list a)
|
||||
return vm::vsnprintf(dst, size, format, a);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int
|
||||
jio_snprintf(char* dst, size_t size, const char* format, ...)
|
||||
{
|
||||
va_list a;
|
||||
va_start(a, format);
|
||||
// extern "C" JNIEXPORT int
|
||||
// jio_snprintf(char* dst, size_t size, const char* format, ...)
|
||||
// {
|
||||
// va_list a;
|
||||
// va_start(a, format);
|
||||
|
||||
int r = jio_vsnprintf(dst, size, format, a);
|
||||
// int r = jio_vsnprintf(dst, size, format, a);
|
||||
|
||||
va_end(a);
|
||||
// va_end(a);
|
||||
|
||||
return r;
|
||||
}
|
||||
// return r;
|
||||
// }
|
||||
|
||||
extern "C" JNIEXPORT int
|
||||
jio_vfprintf(FILE* stream, const char* format, va_list a)
|
||||
@ -2616,15 +2720,15 @@ jio_vfprintf(FILE* stream, const char* format, va_list a)
|
||||
return vfprintf(stream, format, a);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int
|
||||
jio_fprintf(FILE* stream, const char* format, ...)
|
||||
{
|
||||
va_list a;
|
||||
va_start(a, format);
|
||||
// extern "C" JNIEXPORT int
|
||||
// jio_fprintf(FILE* stream, const char* format, ...)
|
||||
// {
|
||||
// va_list a;
|
||||
// va_start(a, format);
|
||||
|
||||
int r = jio_vfprintf(stream, format, a);
|
||||
// int r = jio_vfprintf(stream, format, a);
|
||||
|
||||
va_end(a);
|
||||
// va_end(a);
|
||||
|
||||
return r;
|
||||
}
|
||||
// return r;
|
||||
// }
|
||||
|
@ -8601,19 +8601,7 @@ compile(MyThread* t, Allocator* allocator, BootContext* bootContext,
|
||||
// method so that we won't be confused if another thread updates the
|
||||
// original while we're working.
|
||||
|
||||
object clone = makeMethod
|
||||
(t, methodVmFlags(t, method),
|
||||
methodReturnCode(t, method),
|
||||
methodParameterCount(t, method),
|
||||
methodParameterFootprint(t, method),
|
||||
methodFlags(t, method),
|
||||
methodOffset(t, method),
|
||||
methodNativeID(t, method),
|
||||
methodName(t, method),
|
||||
methodSpec(t, method),
|
||||
methodAddendum(t, method),
|
||||
methodClass(t, method),
|
||||
methodCode(t, method));
|
||||
object clone = methodClone(t, method);
|
||||
|
||||
loadMemoryBarrier();
|
||||
|
||||
|
@ -1928,10 +1928,16 @@ RegisterNatives(Thread* t, jclass c, const JNINativeMethod* methods,
|
||||
|
||||
for (int i = 0; i < methodCount; ++i) {
|
||||
if (methods[i].function) {
|
||||
object method = findMethod(t, c, methods[i].name, methods[i].signature);
|
||||
if (UNLIKELY(t->exception)) return -1;
|
||||
object method = findMethodOrNull
|
||||
(t, jclassVmClass(t, *c), methods[i].name, methods[i].signature);
|
||||
|
||||
registerNative(t, method, methods[i].function);
|
||||
if (method == 0 or (methodFlags(t, method) & ACC_NATIVE) == 0) {
|
||||
// The JNI spec says we must throw a NoSuchMethodError in this
|
||||
// case, but that would prevent using a code shrinker like
|
||||
// ProGuard effectively. Instead, we just ignore it.
|
||||
} else {
|
||||
registerNative(t, method, methods[i].function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3546,9 +3546,8 @@ findInTable(Thread* t, object table, object name, object spec,
|
||||
}
|
||||
|
||||
object
|
||||
findInHierarchy(Thread* t, object class_, object name, object spec,
|
||||
object (*find)(Thread*, object, object, object),
|
||||
Machine::Type errorType)
|
||||
findInHierarchyOrNull(Thread* t, object class_, object name, object spec,
|
||||
object (*find)(Thread*, object, object, object))
|
||||
{
|
||||
object originalClass = class_;
|
||||
|
||||
@ -3570,15 +3569,6 @@ findInHierarchy(Thread* t, object class_, object name, object spec,
|
||||
}
|
||||
}
|
||||
|
||||
if (o == 0) {
|
||||
object message = makeString
|
||||
(t, "%s %s not found in %s",
|
||||
&byteArrayBody(t, name, 0),
|
||||
&byteArrayBody(t, spec, 0),
|
||||
&byteArrayBody(t, className(t, originalClass), 0));
|
||||
t->exception = t->m->classpath->makeThrowable(t, errorType, message);
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -2127,11 +2127,11 @@ object
|
||||
resolveClass(Thread* t, object loader, object name, bool throw_ = true);
|
||||
|
||||
inline object
|
||||
resolveClass(Thread* t, object loader, const char* name)
|
||||
resolveClass(Thread* t, object loader, const char* name, bool throw_ = true)
|
||||
{
|
||||
PROTECT(t, loader);
|
||||
object n = makeByteArray(t, "%s", name);
|
||||
return resolveClass(t, loader, n);
|
||||
return resolveClass(t, loader, n, throw_);
|
||||
}
|
||||
|
||||
object
|
||||
@ -2211,6 +2211,16 @@ findFieldInClass(Thread* t, object class_, object name, object spec)
|
||||
(t, classFieldTable(t, class_), name, spec, fieldName, fieldSpec);
|
||||
}
|
||||
|
||||
inline object
|
||||
findFieldInClass2(Thread* t, object class_, const char* name, const char* spec)
|
||||
{
|
||||
PROTECT(t, class_);
|
||||
object n = makeByteArray(t, "%s", name);
|
||||
PROTECT(t, n);
|
||||
object s = makeByteArray(t, "%s", spec);
|
||||
return findFieldInClass(t, class_, n, s);
|
||||
}
|
||||
|
||||
inline object
|
||||
findMethodInClass(Thread* t, object class_, object name, object spec)
|
||||
{
|
||||
@ -2219,9 +2229,27 @@ findMethodInClass(Thread* t, object class_, object name, object spec)
|
||||
}
|
||||
|
||||
object
|
||||
findInHierarchyOrNull(Thread* t, object class_, object name, object spec,
|
||||
object (*find)(Thread*, object, object, object));
|
||||
|
||||
inline object
|
||||
findInHierarchy(Thread* t, object class_, object name, object spec,
|
||||
object (*find)(Thread*, object, object, object),
|
||||
Machine::Type errorType);
|
||||
Machine::Type errorType)
|
||||
{
|
||||
object o = findInHierarchyOrNull(t, class_, name, spec, find);
|
||||
|
||||
if (o == 0) {
|
||||
object message = makeString
|
||||
(t, "%s %s not found in %s",
|
||||
&byteArrayBody(t, name, 0),
|
||||
&byteArrayBody(t, spec, 0),
|
||||
&byteArrayBody(t, className(t, class_), 0));
|
||||
t->exception = t->m->classpath->makeThrowable(t, errorType, message);
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
inline object
|
||||
findMethod(Thread* t, object class_, object name, object spec)
|
||||
@ -2230,6 +2258,16 @@ findMethod(Thread* t, object class_, object name, object spec)
|
||||
(t, class_, name, spec, findMethodInClass, Machine::NoSuchMethodErrorType);
|
||||
}
|
||||
|
||||
inline object
|
||||
findMethodOrNull(Thread* t, object class_, const char* name, const char* spec)
|
||||
{
|
||||
PROTECT(t, class_);
|
||||
object n = makeByteArray(t, "%s", name);
|
||||
PROTECT(t, n);
|
||||
object s = makeByteArray(t, "%s", spec);
|
||||
return findInHierarchyOrNull(t, class_, n, s, findMethodInClass);
|
||||
}
|
||||
|
||||
inline object
|
||||
findVirtualMethod(Thread* t, object method, object class_)
|
||||
{
|
||||
@ -3066,6 +3104,24 @@ defineClass(Thread* t, object loader, const uint8_t* buffer, unsigned length);
|
||||
void
|
||||
dumpHeap(Thread* t, FILE* out);
|
||||
|
||||
inline object
|
||||
methodClone(Thread* t, object method)
|
||||
{
|
||||
return makeMethod
|
||||
(t, methodVmFlags(t, method),
|
||||
methodReturnCode(t, method),
|
||||
methodParameterCount(t, method),
|
||||
methodParameterFootprint(t, method),
|
||||
methodFlags(t, method),
|
||||
methodOffset(t, method),
|
||||
methodNativeID(t, method),
|
||||
methodName(t, method),
|
||||
methodSpec(t, method),
|
||||
methodAddendum(t, method),
|
||||
methodClass(t, method),
|
||||
methodCode(t, method));
|
||||
}
|
||||
|
||||
} // namespace vm
|
||||
|
||||
void
|
||||
|
29
src/openjdk/jni_md.h
Normal file
29
src/openjdk/jni_md.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* Copyright (c) 2010, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
#ifndef JNI_MD_H
|
||||
#define JNI_MD_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#if (defined __MINGW32__) || (defined _MSC_VER)
|
||||
# define JNIEXPORT __declspec(dllexport)
|
||||
#else // not (defined __MINGW32__) || (defined _MSC_VER)
|
||||
# define JNIEXPORT __attribute__ ((visibility("default")))
|
||||
#endif // not (defined __MINGW32__) || (defined _MSC_VER)
|
||||
|
||||
#define JNIIMPORT
|
||||
#define JNICALL
|
||||
|
||||
typedef int32_t jint;
|
||||
typedef int64_t jlong;
|
||||
typedef int8_t jbyte;
|
||||
|
||||
#endif//JNI_MD_H
|
@ -44,6 +44,10 @@
|
||||
(void* function)
|
||||
(uint8_t fast))
|
||||
|
||||
(type nativeIntercept
|
||||
(extends native)
|
||||
(object original))
|
||||
|
||||
(pod exceptionHandler
|
||||
(uint16_t start)
|
||||
(uint16_t end)
|
||||
|
Loading…
Reference in New Issue
Block a user