Skip to content

Commit 276fb09

Browse files
Googlercopybara-github
authored andcommitted
Packaging support for deploy JAR embedded JDK files (hermetic Java).
This is the initial implementation that supports packaging runtime needed JDK files into deploy JAR, which is part of the phase III development for hermetic Java support (b/212719968). - The runtime needed JDK files specified via --resources flag are packaged as regular JAR entries in deploy JAR. Any JDK file that needs to be packaged at page aligned offset should not be included in --resource input list. - JDK 'lib/modules' file has page alignment requirement (runtime mmap the modules image). A new singlejar flag is introduced for specifying the lib/modules file: * --jdk_lib_modules <jdk_lib_modules_path> Following manifest attribute is written in the JAR META-INF/MANIFEST.MF, if lib/modules is specified via the new flag: * JDK-Lib-Modules-Offset: <offset> The lib/modules offset information will be used at runtime in JDK when mapping the file. Please see more details on design requirements/considerations and decisions in[] The support for launcher part is handled by unknown commit. RELNOTES: Packaging support for deploy JAR embedded JDK files (hermetic Java). PiperOrigin-RevId: 437310998
1 parent 0365645 commit 276fb09

File tree

6 files changed

+109
-19
lines changed

6 files changed

+109
-19
lines changed

src/tools/singlejar/options.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ bool Options::ParseToken(ArgTokenStream *tokens) {
3737
tokens->MatchAndSet("--main_class", &main_class) ||
3838
tokens->MatchAndSet("--java_launcher", &java_launcher) ||
3939
tokens->MatchAndSet("--cds_archive", &cds_archive) ||
40+
tokens->MatchAndSet("--jdk_lib_modules", &jdk_lib_modules) ||
4041
tokens->MatchAndSet("--deploy_manifest_lines", &manifest_lines) ||
4142
tokens->MatchAndSet("--sources", &input_jars) ||
4243
tokens->MatchAndSet("--resources", &resources) ||

src/tools/singlejar/options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class Options {
4545
std::string main_class;
4646
std::string java_launcher;
4747
std::string cds_archive;
48+
std::string jdk_lib_modules;
4849
std::vector<std::string> manifest_lines;
4950
std::vector<std::pair<std::string, std::string> > input_jars;
5051
std::vector<std::string> resources;

src/tools/singlejar/options_test.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ TEST(OptionsTest, SingleOptargs) {
7070
"--extra_build_info", "extra_build_line1",
7171
"--build_info_file", "build_file2",
7272
"--extra_build_info", "extra_build_line2",
73-
"--cds_archive", "classes.jsa"};
73+
"--cds_archive", "classes.jsa",
74+
"--jdk_lib_modules", "modules"};
7475
Options options;
7576
options.ParseCommandLine(arraysize(args), args);
7677

@@ -84,6 +85,7 @@ TEST(OptionsTest, SingleOptargs) {
8485
EXPECT_EQ("extra_build_line1", options.build_info_lines[0]);
8586
EXPECT_EQ("extra_build_line2", options.build_info_lines[1]);
8687
EXPECT_EQ("classes.jsa", options.cds_archive);
88+
EXPECT_EQ("modules", options.jdk_lib_modules);
8789
}
8890

8991
TEST(OptionsTest, MultiOptargs) {

src/tools/singlejar/output_jar.cc

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,17 @@ int OutputJar::Doit(Options *options) {
129129
manifest_.AppendLine("Main-Class: " + options_->main_class);
130130
}
131131

132-
// Copy CDS archive file (.jsa) if it is set.
132+
// Copy CDS archive file (.jsa) if it is set. Page aligned start offset
133+
// is required.
133134
if (!options_->cds_archive.empty()) {
134-
AppendCDSArchive(options->cds_archive);
135+
AppendPageAlignedFile(options->cds_archive, "Jsa-Offset", "cds.archive");
136+
}
137+
138+
// Copy JDK lib/modules if set. Page aligned start offset is required for
139+
// the file.
140+
if (!options_->jdk_lib_modules.empty()) {
141+
AppendPageAlignedFile(options_->jdk_lib_modules,
142+
"JDK-Lib-Modules-Offset", std::string());
135143
}
136144

137145
if (options_->multi_release) {
@@ -1041,22 +1049,25 @@ off64_t OutputJar::PageAlignedAppendFile(const std::string &file_path) {
10411049
return aligned_offset;
10421050
}
10431051

1044-
void OutputJar::AppendCDSArchive(const std::string &cds_archive) {
1052+
void OutputJar::AppendPageAlignedFile(const std::string &file,
1053+
const std::string &manifest_attr_name,
1054+
const std::string &property_name) {
10451055
// Align the shared archive start offset at page alignment, which is
10461056
// required by mmap.
1047-
off64_t aligned_offset = OutputJar::PageAlignedAppendFile(cds_archive);
1048-
1049-
// Write the file offset of the shared archive section as a manifest
1050-
// attribute.
1051-
char cds_manifest_attr[50];
1052-
snprintf( cds_manifest_attr, sizeof(cds_manifest_attr),
1053-
"Jsa-Offset: %ld", (long)aligned_offset); // NOLINT(runtime/int,
1054-
// google-runtime-int)
1055-
manifest_.AppendLine(cds_manifest_attr);
1056-
1057-
// Add to build_properties
1058-
build_properties_.AddProperty("cds.archive",
1059-
cds_archive.c_str());
1057+
off64_t aligned_offset = OutputJar::PageAlignedAppendFile(file);
1058+
1059+
// Write the start offset of the copied content as a manifest attribute.
1060+
char manifest_attr[50];
1061+
snprintf(manifest_attr, sizeof(manifest_attr),
1062+
"%s: %ld", manifest_attr_name.c_str(),
1063+
(long)aligned_offset); // NOLINT(runtime/int,
1064+
// google-runtime-int)
1065+
manifest_.AppendLine(manifest_attr);
1066+
1067+
if (!property_name.empty()) {
1068+
// Add to build_properties.
1069+
build_properties_.AddProperty(property_name.c_str(), file.c_str());
1070+
}
10601071
}
10611072

10621073
void OutputJar::ExtraCombiner(const std::string &entry_name,

src/tools/singlejar/output_jar.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,11 @@ class OutputJar {
9696
// Set classpath resource with given resource name and path.
9797
void ClasspathResource(const std::string& resource_name,
9898
const std::string& resource_path);
99-
// Append CDS archive file.
100-
void AppendCDSArchive(const std::string &cds_archive);
10199
// Append file starting at page boundary.
102100
off64_t PageAlignedAppendFile(const std::string &file_path);
101+
void AppendPageAlignedFile(const std::string &file,
102+
const std::string &manifest_attr_name,
103+
const std::string &property_name);
103104
// Append data from the file specified by file_path.
104105
void AppendFile(Options *options, const char *const file_path);
105106
// Copy 'count' bytes starting at 'offset' from the given file.

src/tools/singlejar/output_jar_simple_test.cc

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,80 @@ TEST_F(OutputJarSimpleTest, CDSArchive) {
307307
EXPECT_PRED2(HasSubstr, build_properties, prop);
308308
}
309309

310+
// --jdk_lib_modules option
311+
TEST_F(OutputJarSimpleTest, JDKLibModules) {
312+
string out_path = OutputFilePath("out.jar");
313+
string launcher_path = CreateTextFile("launcher", "Dummy");
314+
string jdk_lib_modules_path = CreateTextFile("modules", "Dummy");
315+
CreateOutput(out_path, {"--java_launcher", launcher_path,
316+
"--jdk_lib_modules", jdk_lib_modules_path});
317+
318+
// Test META-INF/MANIFEST.MF attribute.
319+
string manifest = GetEntryContents(out_path, "META-INF/MANIFEST.MF");
320+
size_t pagesize;
321+
#ifndef _WIN32
322+
pagesize = sysconf(_SC_PAGESIZE);
323+
#else
324+
SYSTEM_INFO si;
325+
GetSystemInfo(&si);
326+
pagesize = si.dwPageSize;
327+
#endif
328+
char attr[128];
329+
snprintf(attr, sizeof(attr), "JDK-Lib-Modules-Offset: %ld", pagesize);
330+
EXPECT_PRED2(HasSubstr, manifest, attr);
331+
}
332+
333+
// --cds_archive & --jdk_lib_modules options
334+
TEST_F(OutputJarSimpleTest, CDSAndJDKLibModules) {
335+
string cds_data = "cafebabe";
336+
string modules_data = "deadbeef";
337+
string out_path = OutputFilePath("out.jar");
338+
string launcher_path = CreateTextFile("launcher", "Dummy");
339+
string cds_archive_path = CreateTextFile("classes.jsa", cds_data.c_str());
340+
string jdk_lib_modules_path = CreateTextFile("modules", modules_data.c_str());
341+
CreateOutput(out_path, {"--java_launcher", launcher_path,
342+
"--cds_archive", cds_archive_path,
343+
"--jdk_lib_modules", jdk_lib_modules_path});
344+
345+
FILE *fp = fopen(out_path.c_str(), "r");
346+
ASSERT_NE(nullptr, fp);
347+
348+
// Test META-INF/MANIFEST.MF attributes.
349+
string manifest = GetEntryContents(out_path, "META-INF/MANIFEST.MF");
350+
size_t pagesize;
351+
#ifndef _WIN32
352+
pagesize = sysconf(_SC_PAGESIZE);
353+
#else
354+
SYSTEM_INFO si;
355+
GetSystemInfo(&si);
356+
pagesize = si.dwPageSize;
357+
#endif
358+
size_t page_aligned_cds_offset = pagesize;
359+
char buf[8];
360+
size_t buf_len = sizeof(buf);
361+
362+
char cds_attr[128];
363+
snprintf(cds_attr, sizeof(cds_attr), "Jsa-Offset: %ld",
364+
page_aligned_cds_offset);
365+
EXPECT_PRED2(HasSubstr, manifest, cds_attr);
366+
367+
fseek(fp, page_aligned_cds_offset, 0);
368+
fread(buf, 1, buf_len, fp);
369+
ASSERT_EQ(cds_data, string(buf, buf_len));
370+
371+
size_t page_aligned_modules_offset = pagesize * 2;
372+
char modules_attr[128];
373+
snprintf(modules_attr, sizeof(modules_attr), "JDK-Lib-Modules-Offset: %ld",
374+
page_aligned_modules_offset);
375+
EXPECT_PRED2(HasSubstr, manifest, modules_attr);
376+
377+
fseek(fp, page_aligned_modules_offset, 0);
378+
fread(buf, 1, buf_len, fp);
379+
ASSERT_EQ(modules_data, string(buf, buf_len));
380+
381+
fclose(fp);
382+
}
383+
310384
// --main_class option.
311385
TEST_F(OutputJarSimpleTest, MainClass) {
312386
string out_path = OutputFilePath("out.jar");

0 commit comments

Comments
 (0)