diff a/src/hotspot/share/classfile/classLoaderExt.cpp b/src/hotspot/share/classfile/classLoaderExt.cpp
--- a/src/hotspot/share/classfile/classLoaderExt.cpp
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp
@@ -57,10 +57,11 @@
 jshort ClassLoaderExt::_max_used_path_index = 0;
 int ClassLoaderExt::_num_module_paths = 0;
 bool ClassLoaderExt::_has_app_classes = false;
 bool ClassLoaderExt::_has_platform_classes = false;
 bool ClassLoaderExt::_has_non_jar_in_classpath = false;
+int ClassLoaderExt::_app_class_exclusion_start_path_index = INT_MAX;
 
 void ClassLoaderExt::append_boot_classpath(ClassPathEntry* new_entry) {
   if (CDSConfig::is_using_archive()) {
     warning("Sharing is only supported for boot loader classes because bootstrap classpath has been appended");
     FileMapInfo::current_info()->set_has_platform_or_app_classes(false);
@@ -103,10 +104,22 @@
     GrowableArray<const char*>* _module_paths;
    public:
     ModulePathsGatherer(JavaThread* current, GrowableArray<const char*>* module_paths) :
       _current(current), _module_paths(module_paths) {}
     void do_module(ModuleEntry* m) {
+      if (m->location() == nullptr) {
+        // This is a dynamic generated module (which we loaded from the static archive) for supporting
+        // dynamic proxies. We don't archive any other such modules.
+        // No need to include such modules in _module_path.
+        assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
+        assert(Modules::is_dynamic_proxy_module(m), "must be");
+        if (log_is_enabled(Info, cds, dynamic, proxy)) {
+          ResourceMark rm;
+          log_info(cds, dynamic, proxy)("Archived dynamic module: %s", m->name()->as_C_string());
+        }
+        return;
+      }
       char* uri = m->location()->as_C_string();
       if (strncmp(uri, "file:", 5) == 0) {
         char* path = ClassLoader::uri_to_path(uri);
         extract_jar_files_from_path(path, _module_paths);
       }
@@ -338,6 +351,78 @@
     log_warning(cds)("CDS heap objects cannot be written because class %s maybe modified by ClassFileLoadHook.",
                      result->external_name());
     HeapShared::disable_writing();
   }
 #endif // INCLUDE_CDS_JAVA_HEAP
+  if (CDSConfig::is_dumping_preimage_static_archive() || CDSConfig::is_dumping_dynamic_archive()) {
+    check_invalid_classpath_index(classpath_index, result);
+  }
 }
+
+ClassPathEntry* ClassLoaderExt::get_class_path_entry(s2 classpath_index) {
+  if (classpath_index < 0) {
+    return nullptr;
+  }
+
+  if (classpath_index == 0) {
+    assert(has_jrt_entry(), "CDS requires modules image");
+    return get_jrt_entry();
+  }
+
+  // Iterate over -Xbootclasspath, if any;
+  int i = 0;
+  for (ClassPathEntry* cpe = first_append_entry(); cpe != nullptr; cpe = cpe->next()) {
+    i++;
+    if (i == classpath_index) {
+      return cpe;
+    }
+  }
+
+  // Iterate over -cp, if any
+  for (ClassPathEntry* cpe = app_classpath_entries(); cpe != nullptr; cpe = cpe->next()) {
+    i++;
+    if (i == classpath_index) {
+      return cpe;
+    }
+  }
+
+  // Iterate over --module-path, if any
+  for (ClassPathEntry* cpe = module_path_entries(); cpe != nullptr; cpe = cpe->next()) {
+    i++;
+    if (i == classpath_index) {
+      return cpe;
+    }
+  }
+
+  return nullptr;
+}
+
+// It's possible to use reflection+setAccessible to call into ClassLoader::defineClass() to
+// pretend that a dynamically generated class comes from a JAR file in the classpath.
+// Detect such classes and exclude them from the archive.
+void ClassLoaderExt::check_invalid_classpath_index(s2 classpath_index, InstanceKlass* ik) {
+  ClassPathEntry *cpe = get_class_path_entry(classpath_index);
+  if (cpe != nullptr && cpe->is_jar_file()) {
+    ClassPathZipEntry *zip = (ClassPathZipEntry*)cpe;
+    JavaThread* current = JavaThread::current();
+    ResourceMark rm(current);
+    const char* const class_name = ik->name()->as_C_string();
+    const char* const file_name = file_name_for_class_name(class_name,
+                                                           ik->name()->utf8_length());
+    if (!zip->has_entry(current, file_name)) {
+      log_warning(cds)("class %s cannot be archived because it was not define from %s as claimed",
+                       class_name, zip->name());
+      ik->set_shared_classpath_index(-1);
+    }
+  }
+}
+
+// -XX:CacheOnlyClassesIn=
+bool ClassLoaderExt::should_be_excluded(InstanceKlass* k) {
+  int path_index = k->shared_classpath_index();
+  if (path_index >= _app_class_exclusion_start_path_index  && path_index < _app_module_paths_start_index) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
