151 } |
151 } |
152 |
152 |
153 return true; |
153 return true; |
154 } |
154 } |
155 |
155 |
156 char* skip_first_path_entry(const char* path) { |
|
157 size_t path_sep_len = strlen(os::path_separator()); |
|
158 char* p = strstr((char*)path, os::path_separator()); |
|
159 if (p != NULL) { |
|
160 debug_only( { |
|
161 size_t image_name_len = strlen(MODULES_IMAGE_NAME); |
|
162 assert(strncmp(p - image_name_len, MODULES_IMAGE_NAME, image_name_len) == 0, |
|
163 "first entry must be the modules image"); |
|
164 } ); |
|
165 p += path_sep_len; |
|
166 } else { |
|
167 debug_only( { |
|
168 assert(ClassLoader::string_ends_with(path, MODULES_IMAGE_NAME), |
|
169 "first entry must be the modules image"); |
|
170 } ); |
|
171 } |
|
172 return p; |
|
173 } |
|
174 |
|
175 bool SharedPathsMiscInfo::check(jint type, const char* path, bool is_static) { |
156 bool SharedPathsMiscInfo::check(jint type, const char* path, bool is_static) { |
176 assert(UseSharedSpaces, "runtime only"); |
157 assert(UseSharedSpaces, "runtime only"); |
177 switch (type) { |
158 switch (type) { |
178 case BOOT_PATH: |
159 case BOOT_PATH: |
179 { |
|
180 // |
|
181 // - Archive contains boot classes only - relaxed boot path check: |
|
182 // Extra path elements appended to the boot path at runtime are allowed. |
|
183 // |
|
184 // - Archive contains application or platform classes - strict boot path check: |
|
185 // Validate the entire runtime boot path, which must be compactible |
|
186 // with the dump time boot path. Appending boot path at runtime is not |
|
187 // allowed. |
|
188 // |
|
189 |
|
190 // The first entry in boot path is the modules_image (guaranteed by |
|
191 // ClassLoader::setup_boot_search_path()). Skip the first entry. The |
|
192 // path of the runtime modules_image may be different from the dump |
|
193 // time path (e.g. the JDK image is copied to a different location |
|
194 // after generating the shared archive), which is acceptable. For most |
|
195 // common cases, the dump time boot path might contain modules_image only. |
|
196 char* runtime_boot_path = Arguments::get_sysclasspath(); |
|
197 char* rp = skip_first_path_entry(runtime_boot_path); |
|
198 char* dp = skip_first_path_entry(path); |
|
199 |
|
200 bool relaxed_check = is_static ? |
|
201 !FileMapInfo::current_info()->header()->has_platform_or_app_classes() : |
|
202 !FileMapInfo::dynamic_info()->header()->has_platform_or_app_classes(); |
|
203 if (dp == NULL && rp == NULL) { |
|
204 break; // ok, both runtime and dump time boot paths have modules_images only |
|
205 } else if (dp == NULL && rp != NULL && relaxed_check) { |
|
206 break; // ok, relaxed check, runtime has extra boot append path entries |
|
207 } else if (dp != NULL && rp != NULL) { |
|
208 size_t num; |
|
209 size_t dp_len = strlen(dp); |
|
210 size_t rp_len = strlen(rp); |
|
211 if (rp_len >= dp_len) { |
|
212 if (relaxed_check) { |
|
213 // only check the leading entries in the runtime boot path, up to |
|
214 // the length of the dump time boot path |
|
215 num = dp_len; |
|
216 } else { |
|
217 // check the full runtime boot path, must match with dump time |
|
218 num = rp_len; |
|
219 } |
|
220 |
|
221 if (os::file_name_strncmp(dp, rp, num) == 0) { |
|
222 // make sure it is the end of an entry in the runtime boot path |
|
223 if (rp[dp_len] == '\0' || rp[dp_len] == os::path_separator()[0]) { |
|
224 break; // ok, runtime and dump time paths match |
|
225 } |
|
226 } |
|
227 } |
|
228 } |
|
229 |
|
230 // The paths are different |
|
231 return fail("[BOOT classpath mismatch, actual =", runtime_boot_path); |
|
232 } |
|
233 break; |
160 break; |
234 case NON_EXIST: |
161 case NON_EXIST: |
235 { |
162 { |
236 struct stat st; |
163 struct stat st; |
237 if (os::stat(path, &st) == 0) { |
164 if (os::stat(path, &st) == 0) { |
240 return fail("File must not exist"); |
167 return fail("File must not exist"); |
241 } |
168 } |
242 } |
169 } |
243 break; |
170 break; |
244 case APP_PATH: |
171 case APP_PATH: |
245 { |
|
246 size_t len = strlen(path); |
|
247 const char *appcp = Arguments::get_appclasspath(); |
|
248 assert(appcp != NULL, "NULL app classpath"); |
|
249 size_t appcp_len = strlen(appcp); |
|
250 if (appcp_len < len) { |
|
251 return fail("Run time APP classpath is shorter than the one at dump time: ", appcp); |
|
252 } |
|
253 // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar. |
|
254 if (os::file_name_strncmp(path, appcp, len) != 0) { |
|
255 return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp); |
|
256 } |
|
257 if (appcp[len] != '\0' && appcp[len] != os::path_separator()[0]) { |
|
258 return fail("Dump time APP classpath is not a proper prefix of run time APP classpath: ", appcp); |
|
259 } |
|
260 } |
|
261 break; |
172 break; |
262 default: |
173 default: |
263 return fail("Corrupted archive file header"); |
174 return fail("Corrupted archive file header"); |
264 } |
175 } |
265 |
176 |