203 _verify_local = BytecodeVerificationLocal; |
203 _verify_local = BytecodeVerificationLocal; |
204 _verify_remote = BytecodeVerificationRemote; |
204 _verify_remote = BytecodeVerificationRemote; |
205 _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes(); |
205 _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes(); |
206 } |
206 } |
207 |
207 |
208 void SharedClassPathEntry::init(const char* name, TRAPS) { |
208 void SharedClassPathEntry::init(const char* name, bool is_modules_image, TRAPS) { |
|
209 assert(DumpSharedSpaces, "dump time only"); |
209 _timestamp = 0; |
210 _timestamp = 0; |
210 _filesize = 0; |
211 _filesize = 0; |
211 |
212 |
212 struct stat st; |
213 struct stat st; |
213 if (os::stat(name, &st) == 0) { |
214 if (os::stat(name, &st) == 0) { |
214 if ((st.st_mode & S_IFMT) == S_IFDIR) { |
215 if ((st.st_mode & S_IFMT) == S_IFDIR) { |
215 _is_dir = true; |
216 _type = dir_entry; |
216 } else { |
217 } else { |
217 _is_dir = false; |
218 // The timestamp of the modules_image is not checked at runtime. |
218 _timestamp = st.st_mtime; |
219 if (is_modules_image) { |
|
220 _type = modules_image_entry; |
|
221 } else { |
|
222 _type = jar_entry; |
|
223 _timestamp = st.st_mtime; |
|
224 } |
219 _filesize = st.st_size; |
225 _filesize = st.st_size; |
220 } |
226 } |
221 } else { |
227 } else { |
222 // The file/dir must exist, or it would not have been added |
228 // The file/dir must exist, or it would not have been added |
223 // into ClassLoader::classpath_entry(). |
229 // into ClassLoader::classpath_entry(). |
234 |
240 |
235 bool SharedClassPathEntry::validate(bool is_class_path) { |
241 bool SharedClassPathEntry::validate(bool is_class_path) { |
236 assert(UseSharedSpaces, "runtime only"); |
242 assert(UseSharedSpaces, "runtime only"); |
237 |
243 |
238 struct stat st; |
244 struct stat st; |
239 const char* name = this->name(); |
245 const char* name; |
|
246 |
|
247 // In order to validate the runtime modules image file size against the archived |
|
248 // size information, we need to obtain the runtime modules image path. The recorded |
|
249 // dump time modules image path in the archive may be different from the runtime path |
|
250 // if the JDK image has beed moved after generating the archive. |
|
251 if (is_modules_image()) { |
|
252 name = ClassLoader::get_jrt_entry()->name(); |
|
253 } else { |
|
254 name = this->name(); |
|
255 } |
|
256 |
240 bool ok = true; |
257 bool ok = true; |
241 log_info(class, path)("checking shared classpath entry: %s", name); |
258 log_info(class, path)("checking shared classpath entry: %s", name); |
242 if (os::stat(name, &st) != 0 && is_class_path) { |
259 if (os::stat(name, &st) != 0 && is_class_path) { |
243 // If the archived module path entry does not exist at runtime, it is not fatal |
260 // If the archived module path entry does not exist at runtime, it is not fatal |
244 // (no need to invalid the shared archive) because the shared runtime visibility check |
261 // (no need to invalid the shared archive) because the shared runtime visibility check |
249 } else if (is_dir()) { |
266 } else if (is_dir()) { |
250 if (!os::dir_is_empty(name)) { |
267 if (!os::dir_is_empty(name)) { |
251 FileMapInfo::fail_continue("directory is not empty: %s", name); |
268 FileMapInfo::fail_continue("directory is not empty: %s", name); |
252 ok = false; |
269 ok = false; |
253 } |
270 } |
254 } else if (is_jar_or_bootimage()) { |
271 } else if ((has_timestamp() && _timestamp != st.st_mtime) || |
255 if (_timestamp != st.st_mtime || |
272 _filesize != st.st_size) { |
256 _filesize != st.st_size) { |
273 ok = false; |
257 ok = false; |
274 if (PrintSharedArchiveAndExit) { |
258 if (PrintSharedArchiveAndExit) { |
275 FileMapInfo::fail_continue(_timestamp != st.st_mtime ? |
259 FileMapInfo::fail_continue(_timestamp != st.st_mtime ? |
276 "Timestamp mismatch" : |
260 "Timestamp mismatch" : |
277 "File size mismatch"); |
261 "File size mismatch"); |
278 } else { |
262 } else { |
279 FileMapInfo::fail_continue("A jar file is not the one used while building" |
263 FileMapInfo::fail_continue("A jar/jimage file is not the one used while building" |
280 " the shared archive file: %s", name); |
264 " the shared archive file: %s", name); |
|
265 } |
|
266 } |
281 } |
267 } |
282 } |
268 return ok; |
283 return ok; |
269 } |
284 } |
270 |
285 |
296 |
311 |
297 // 1. boot class path |
312 // 1. boot class path |
298 int i = 0; |
313 int i = 0; |
299 ClassPathEntry* cpe = jrt; |
314 ClassPathEntry* cpe = jrt; |
300 while (cpe != NULL) { |
315 while (cpe != NULL) { |
301 const char* type = ((cpe == jrt) ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir")); |
316 bool is_jrt = (cpe == jrt); |
|
317 const char* type = (is_jrt ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir")); |
302 log_info(class, path)("add main shared path (%s) %s", type, cpe->name()); |
318 log_info(class, path)("add main shared path (%s) %s", type, cpe->name()); |
303 SharedClassPathEntry* ent = shared_path(i); |
319 SharedClassPathEntry* ent = shared_path(i); |
304 ent->init(cpe->name(), THREAD); |
320 ent->init(cpe->name(), is_jrt, THREAD); |
305 if (cpe != jrt) { // No need to do jimage. |
321 if (!is_jrt) { // No need to do the modules image. |
306 EXCEPTION_MARK; // The following call should never throw, but would exit VM on error. |
322 EXCEPTION_MARK; // The following call should never throw, but would exit VM on error. |
307 update_shared_classpath(cpe, ent, THREAD); |
323 update_shared_classpath(cpe, ent, THREAD); |
308 } |
324 } |
309 cpe = ClassLoader::get_next_boot_classpath_entry(cpe); |
325 cpe = ClassLoader::get_next_boot_classpath_entry(cpe); |
310 i++; |
326 i++; |
315 // 2. app class path |
331 // 2. app class path |
316 ClassPathEntry *acpe = ClassLoader::app_classpath_entries(); |
332 ClassPathEntry *acpe = ClassLoader::app_classpath_entries(); |
317 while (acpe != NULL) { |
333 while (acpe != NULL) { |
318 log_info(class, path)("add app shared path %s", acpe->name()); |
334 log_info(class, path)("add app shared path %s", acpe->name()); |
319 SharedClassPathEntry* ent = shared_path(i); |
335 SharedClassPathEntry* ent = shared_path(i); |
320 ent->init(acpe->name(), THREAD); |
336 ent->init(acpe->name(), false, THREAD); |
321 EXCEPTION_MARK; |
337 EXCEPTION_MARK; |
322 update_shared_classpath(acpe, ent, THREAD); |
338 update_shared_classpath(acpe, ent, THREAD); |
323 acpe = acpe->next(); |
339 acpe = acpe->next(); |
324 i++; |
340 i++; |
325 } |
341 } |
327 // 3. module path |
343 // 3. module path |
328 ClassPathEntry *mpe = ClassLoader::module_path_entries(); |
344 ClassPathEntry *mpe = ClassLoader::module_path_entries(); |
329 while (mpe != NULL) { |
345 while (mpe != NULL) { |
330 log_info(class, path)("add module path %s",mpe->name()); |
346 log_info(class, path)("add module path %s",mpe->name()); |
331 SharedClassPathEntry* ent = shared_path(i); |
347 SharedClassPathEntry* ent = shared_path(i); |
332 ent->init(mpe->name(), THREAD); |
348 ent->init(mpe->name(), false, THREAD); |
333 EXCEPTION_MARK; |
349 EXCEPTION_MARK; |
334 update_shared_classpath(mpe, ent, THREAD); |
350 update_shared_classpath(mpe, ent, THREAD); |
335 mpe = mpe->next(); |
351 mpe = mpe->next(); |
336 i++; |
352 i++; |
337 } |
353 } |
415 |
431 |
416 void FileMapInfo::update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS) { |
432 void FileMapInfo::update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS) { |
417 ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); |
433 ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); |
418 ResourceMark rm(THREAD); |
434 ResourceMark rm(THREAD); |
419 jint manifest_size; |
435 jint manifest_size; |
420 bool isSigned; |
|
421 |
436 |
422 if (cpe->is_jar_file()) { |
437 if (cpe->is_jar_file()) { |
|
438 assert(ent->is_jar(), "the shared class path entry is not a JAR file"); |
423 char* manifest = ClassLoaderExt::read_manifest(cpe, &manifest_size, CHECK); |
439 char* manifest = ClassLoaderExt::read_manifest(cpe, &manifest_size, CHECK); |
424 if (manifest != NULL) { |
440 if (manifest != NULL) { |
425 ManifestStream* stream = new ManifestStream((u1*)manifest, |
441 ManifestStream* stream = new ManifestStream((u1*)manifest, |
426 manifest_size); |
442 manifest_size); |
427 isSigned = stream->check_is_signed(); |
443 if (stream->check_is_signed()) { |
428 if (isSigned) { |
444 ent->set_is_signed(); |
429 ent->set_is_signed(true); |
|
430 } else { |
445 } else { |
431 // Copy the manifest into the shared archive |
446 // Copy the manifest into the shared archive |
432 manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK); |
447 manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK); |
433 Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data, |
448 Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data, |
434 manifest_size, |
449 manifest_size, |
435 THREAD); |
450 THREAD); |
436 char* p = (char*)(buf->data()); |
451 char* p = (char*)(buf->data()); |
437 memcpy(p, manifest, manifest_size); |
452 memcpy(p, manifest, manifest_size); |
438 ent->set_manifest(buf); |
453 ent->set_manifest(buf); |
439 ent->set_is_signed(false); |
|
440 } |
454 } |
441 } |
455 } |
442 } |
456 } |
443 } |
457 } |
444 |
458 |