Skip to content

Commit d0a6096

Browse files
committed
add support for accessing embedded JARs as if they were directories
This allows OpenJDK to access time zone data which is normally found under java.home, but which we must embed in the executable itself to create a self-contained build. The VM intercepts various file operations, looking for paths which start with a prefix specified by the avian.embed.prefix property and redirecting those operations to an embedded JAR. For example, if avian.embed.prefix is "/avian-embedded", and code calls File.exists() with a path of "/avian-embedded/javahomeJar/foo.txt", the VM looks for a function named javahomeJar via dlsym, calls the function to find the memory region containing the embeded JAR, and finally consults the JAR to see if the file "foo.txt" exists.
1 parent 4cb796d commit d0a6096

18 files changed

+771
-219
lines changed

makefile

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,29 @@ classpath = avian
5252

5353
test-executable = $(executable)
5454
boot-classpath = $(classpath-build)
55-
java-home = /avian-embedded
55+
embed-prefix = /avian-embedded
5656

5757
ifdef openjdk
5858
ifdef openjdk-src
5959
include openjdk-src.mk
6060
options := $(options)-openjdk-src
6161
classpath-objects = $(openjdk-objects)
62-
classpath-cflags = -DAVIAN_OPENJDK_SRC
62+
classpath-cflags = -DAVIAN_OPENJDK_SRC -DBOOT_JAVAHOME
6363
openjdk-jar-dep = $(build)/openjdk-jar.dep
6464
classpath-jar-dep = $(openjdk-jar-dep)
65+
javahome = $(embed-prefix)/javahomeJar
66+
javahome-files = lib/zi
67+
javahome-object = $(build)/javahome-jar.o
6568
else
6669
options := $(options)-openjdk
6770
test-executable = $(executable-dynamic)
6871
library-path = LD_LIBRARY_PATH=$(build)
69-
java-home = $(openjdk)/jre
72+
javahome = $(openjdk)/jre
7073
endif
7174

7275
classpath = openjdk
7376
boot-classpath := $(boot-classpath):$(openjdk)/jre/lib/rt.jar
77+
build-javahome = $(openjdk)/jre
7478
endif
7579

7680
ifeq ($(classpath),avian)
@@ -120,7 +124,8 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
120124
common-cflags = $(warnings) -fno-rtti -fno-exceptions -fno-omit-frame-pointer \
121125
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \
122126
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
123-
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(java-home)\"
127+
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
128+
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\"
124129

125130
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
126131
"-I$(JAVA_HOME)/include/linux" -I$(src) -pthread
@@ -593,12 +598,6 @@ $(driver-dynamic-object): $(driver-source)
593598
$(boot-object): $(boot-source)
594599
$(compile-object)
595600

596-
$(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep)
597-
@echo "creating $(@)"
598-
(wd=$$(pwd) && \
599-
cd $(classpath-build) && \
600-
$(jar) c0f "$$($(native-path) "$${wd}/$(@)")" .)
601-
602601
$(build)/binaryToObject-main.o: $(src)/binaryToObject/main.cpp
603602
$(build-cxx) -c $(^) -o $(@)
604603

@@ -620,11 +619,28 @@ $(build)/binaryToObject-pe.o: $(src)/binaryToObject/pe.cpp
620619
$(converter): $(converter-objects)
621620
$(build-cxx) $(^) -o $(@)
622621

622+
$(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep)
623+
@echo "creating $(@)"
624+
(wd=$$(pwd) && \
625+
cd $(classpath-build) && \
626+
$(jar) c0f "$$($(native-path) "$${wd}/$(@)")" .)
627+
623628
$(classpath-object): $(build)/classpath.jar $(converter)
624629
@echo "creating $(@)"
625630
$(converter) $(<) $(@) _binary_classpath_jar_start \
626631
_binary_classpath_jar_end $(platform) $(arch)
627632

633+
$(build)/javahome.jar: $(foreach x,$(javahome-files),$(build-javahome)/$(x))
634+
@echo "creating $(@)"
635+
(wd=$$(pwd) && \
636+
cd $(build-javahome) && \
637+
$(jar) c0f "$$($(native-path) "$${wd}/$(@)")" $(javahome-files))
638+
639+
$(javahome-object): $(build)/javahome.jar $(converter)
640+
@echo "creating $(@)"
641+
$(converter) $(<) $(@) _binary_javahome_jar_start \
642+
_binary_javahome_jar_end $(platform) $(arch)
643+
628644
$(generator-objects): $(generator-depends)
629645
$(generator-objects): $(build)/%-build.o: $(src)/%.cpp
630646
@echo "compiling $(@)"
@@ -651,7 +667,8 @@ $(bootimage-object): $(bootimage-bin) $(converter)
651667
writable executable
652668

653669
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
654-
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-object)
670+
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-object) \
671+
$(javahome-object)
655672

656673
$(executable): $(executable-objects)
657674
@echo "linking $(@)"
@@ -696,18 +713,16 @@ else
696713
$(ld) $(^) $(rdynamic) $(lflags) -o $(@)
697714
endif
698715

699-
dynamic-library-objects = $(vm-objects) $(dynamic-object) \
700-
$(classpath-objects) $(vm-heapwalk-objects) $(boot-object) \
701-
$(vm-classpath-object) $(classpath-libraries)
702-
703-
$(dynamic-library): $(dynamic-library-objects)
716+
$(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
717+
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-object) \
718+
$(classpath-libraries) $(javahome-object)
704719
@echo "linking $(@)"
705720
ifdef msvc
706-
$(ld) $(shared) $(lflags) $(dynamic-library-objects) -out:$(@) \
707-
-PDB:$(@).pdb -IMPLIB:$(build)/$(name).lib -MANIFESTFILE:$(@).manifest
721+
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
722+
-IMPLIB:$(build)/$(name).lib -MANIFESTFILE:$(@).manifest
708723
$(mt) -manifest $(@).manifest -outputresource:"$(@);2"
709724
else
710-
$(ld) $(dynamic-library-objects) -Wl,--version-script=openjdk.ld \
725+
$(ld) $(^) -Wl,--version-script=openjdk.ld \
711726
$(shared) $(lflags) $(bootimage-lflags) -o $(@)
712727
endif
713728
$(strip) $(strip-all) $(@)

src/boot.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ extern "C" {
5252

5353
}
5454

55+
#undef SYMBOL
56+
5557
#endif//BOOT_IMAGE
5658

5759
#ifdef BOOT_CLASSPATH
@@ -76,4 +78,32 @@ extern "C" {
7678

7779
}
7880

81+
#undef SYMBOL
82+
7983
#endif//BOOT_CLASSPATH
84+
85+
#ifdef BOOT_JAVAHOME
86+
87+
#if (defined __MINGW32__) || (defined _MSC_VER)
88+
# define SYMBOL(x) binary_javahome_jar_##x
89+
#else
90+
# define SYMBOL(x) _binary_javahome_jar_##x
91+
#endif
92+
93+
extern "C" {
94+
95+
extern const uint8_t SYMBOL(start)[];
96+
extern const uint8_t SYMBOL(end)[];
97+
98+
EXPORT const uint8_t*
99+
javahomeJar(unsigned* size)
100+
{
101+
*size = SYMBOL(end) - SYMBOL(start);
102+
return SYMBOL(start);
103+
}
104+
105+
}
106+
107+
#undef SYMBOL
108+
109+
#endif//BOOT_JAVAHOME

src/builtin.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,9 @@ Avian_avian_SystemClassLoader_resourceExists
8585
RUNTIME_ARRAY(char, n, stringLength(t, name) + 1);
8686
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
8787

88-
bool r = static_cast<Finder*>(systemClassLoaderFinder(t, loader))->exists
89-
(RUNTIME_ARRAY_BODY(n));
88+
unsigned length;
89+
bool r = static_cast<Finder*>(systemClassLoaderFinder(t, loader))->stat
90+
(RUNTIME_ARRAY_BODY(n), &length) == System::TypeFile;
9091

9192
// fprintf(stderr, "resource %s exists? %d\n", n, r);
9293

src/classpath-avian.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ enumerateThreads(Thread* t, Thread* x, object array, unsigned* index,
128128
namespace vm {
129129

130130
Classpath*
131-
makeClasspath(System*, Allocator* allocator, const char*)
131+
makeClasspath(System*, Allocator* allocator, const char*, const char*)
132132
{
133133
return new (allocator->allocate(sizeof(local::MyClasspath)))
134134
local::MyClasspath(allocator);

0 commit comments

Comments
 (0)