diff a/src/hotspot/share/cds/cdsProtectionDomain.cpp b/src/hotspot/share/cds/cdsProtectionDomain.cpp
--- a/src/hotspot/share/cds/cdsProtectionDomain.cpp
+++ b/src/hotspot/share/cds/cdsProtectionDomain.cpp
@@ -58,10 +58,14 @@
     //   The ProtectionDomains are cached in the corresponding ModuleEntries
     //   for fast access by the VM.
     // all packages from module image are already created during VM bootstrap in
     // Modules::define_module().
     assert(pkg_entry != nullptr, "archived class in module image cannot be from unnamed package");
+    Handle archived_pd = get_archived_protection_domain(THREAD, ik);
+    if (archived_pd.not_null()) {
+      return archived_pd;
+    }
     ModuleEntry* mod_entry = pkg_entry->module();
     return get_shared_protection_domain(class_loader, mod_entry, THREAD);
   } else {
     // For shared app/platform classes originated from JAR files on the class path:
     //   Each of the 3 SystemDictionaryShared::_shared_xxx arrays has the same length
@@ -86,22 +90,28 @@
     //
     //   Note that if an element of these 3 _shared_xxx arrays is null, it will be initialized by
     //   the corresponding SystemDictionaryShared::get_shared_xxx() function.
     Handle manifest = get_shared_jar_manifest(index, CHECK_NH);
     Handle url = get_shared_jar_url(index, CHECK_NH);
-    int index_offset = index - ClassLoaderExt::app_class_paths_start_index();
-    if (index_offset < PackageEntry::max_index_for_defined_in_class_path()) {
-      if (pkg_entry == nullptr || !pkg_entry->is_defined_by_cds_in_class_path(index_offset)) {
-        // define_shared_package only needs to be called once for each package in a jar specified
-        // in the shared class path.
-        define_shared_package(class_name, class_loader, manifest, url, CHECK_NH);
-        if (pkg_entry != nullptr) {
-          pkg_entry->set_defined_by_cds_in_class_path(index_offset);
+    if (!CDSConfig::is_loading_packages()) {
+      int index_offset = index - ClassLoaderExt::app_class_paths_start_index();
+      if (index_offset < PackageEntry::max_index_for_defined_in_class_path()) {
+        if (pkg_entry == nullptr || !pkg_entry->is_defined_by_cds_in_class_path(index_offset)) {
+          // define_shared_package only needs to be called once for each package in a jar specified
+          // in the shared class path.
+          define_shared_package(class_name, class_loader, manifest, url, CHECK_NH);
+          if (pkg_entry != nullptr) {
+            pkg_entry->set_defined_by_cds_in_class_path(index_offset);
+          }
         }
+      } else {
+        define_shared_package(class_name, class_loader, manifest, url, CHECK_NH);
       }
-    } else {
-      define_shared_package(class_name, class_loader, manifest, url, CHECK_NH);
+    }
+    Handle archived_pd = get_archived_protection_domain(THREAD, ik);
+    if (archived_pd.not_null()) {
+      return archived_pd;
     }
     return get_shared_protection_domain(class_loader, index, url, THREAD);
   }
 }
 
@@ -215,10 +225,39 @@
   url_h = Handle(THREAD, shared_jar_url(shared_path_index));
   assert(url_h.not_null(), "sanity");
   return url_h;
 }
 
+Handle CDSProtectionDomain::get_archived_protection_domain(JavaThread* current, InstanceKlass* klass) {
+  oop pd = nullptr;
+
+  if (CDSConfig::is_loading_protection_domains()) {
+    oop mirror;
+    if (klass->has_archived_mirror_index()) {
+      mirror = klass->archived_java_mirror();
+    } else {
+      mirror = klass->java_mirror();
+    }
+
+    if (mirror != nullptr) {
+      pd = java_lang_Class::protection_domain(mirror);
+    }
+  }
+
+  if (log_is_enabled(Info, cds, protectiondomain)) {
+    ResourceMark rm;
+    log_info(cds, protectiondomain)("Archived protection domain for %s = %s", klass->external_name(),
+                                    (pd == nullptr) ? "none" : "found");
+  }
+
+  if (pd == nullptr) {
+    return Handle();
+  } else {
+    return Handle(current, pd);
+  }
+}
+
 // Get the ProtectionDomain associated with the CodeSource from the classloader.
 Handle CDSProtectionDomain::get_protection_domain_from_classloader(Handle class_loader,
                                                                       Handle url, TRAPS) {
   // CodeSource cs = new CodeSource(url, null);
   Handle cs = JavaCalls::construct_new_instance(vmClasses::CodeSource_klass(),
