Bypass catalog if provided systemId does not exist

Signed-off-by: Lukas Jungmann <lukas.jungmann@oracle.com>
diff --git a/jaxb-ri/xjc/src/main/java/com/sun/tools/xjc/api/impl/s2j/SchemaCompilerImpl.java b/jaxb-ri/xjc/src/main/java/com/sun/tools/xjc/api/impl/s2j/SchemaCompilerImpl.java
index 540d98b..c90c1ee 100644
--- a/jaxb-ri/xjc/src/main/java/com/sun/tools/xjc/api/impl/s2j/SchemaCompilerImpl.java
+++ b/jaxb-ri/xjc/src/main/java/com/sun/tools/xjc/api/impl/s2j/SchemaCompilerImpl.java
@@ -40,6 +40,8 @@
 import org.glassfish.jaxb.core.unmarshaller.DOMScanner;
 import org.glassfish.jaxb.core.v2.util.XmlFactory;
 import com.sun.xml.xsom.XSSchemaSet;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 
 import org.w3c.dom.Element;
 import org.w3c.dom.ls.LSInput;
@@ -213,8 +215,7 @@
                             // XSOM passes the namespace URI to the publicID parameter.
                             // we do the same here .
                             InputSource is = opts.entityResolver.resolveEntity(namespaceURI, systemId == null ? "" : systemId);
-                            if (is == null) return null;
-                            return new LSInputSAXWrapper(is);
+                            return isExists(is) ? new LSInputSAXWrapper(is) : null;
                         } catch (SAXException e) {
                             // TODO: is this sufficient?
                             return null;
@@ -292,6 +293,21 @@
             errorListener.fatalError(exception);
     }
 
+    private static boolean isExists(InputSource is) {
+        if (is == null) {
+            return false;
+        }
+        try {
+            URI uri = new URI(is.getSystemId());
+            if ("file".equals(uri.getScheme())) {
+                return Files.exists(Paths.get(uri));
+            }
+        } catch (URISyntaxException ex) {
+            //ignore, let it be handled by parser as is
+        }
+        return true;
+    }
+
     /**
      * We use JAXP 1.3 to do a schema correctness check, but we know
      * it doesn't always work. So in case some people hit the problem,
diff --git a/jaxb-ri/xjc/src/main/java/com/sun/tools/xjc/reader/internalizer/DOMForest.java b/jaxb-ri/xjc/src/main/java/com/sun/tools/xjc/reader/internalizer/DOMForest.java
index 48e1a25..1aa897c 100644
--- a/jaxb-ri/xjc/src/main/java/com/sun/tools/xjc/reader/internalizer/DOMForest.java
+++ b/jaxb-ri/xjc/src/main/java/com/sun/tools/xjc/reader/internalizer/DOMForest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -43,6 +43,10 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.*;
 
 import static org.glassfish.jaxb.core.v2.util.XmlFactory.allowExternalAccess;
@@ -263,11 +267,26 @@
         InputSource is=null;
         
         // allow entity resolver to find the actual byte stream.
-        if( entityResolver!=null )
+        if( entityResolver!=null ) {
             is = entityResolver.resolveEntity(null,systemId);
-        if( is==null )
+        }
+        if (is == null) {
             is = new InputSource(systemId);
-        
+        } else {
+            try {
+                URI uri = new URI(is.getSystemId());
+                if ("file".equals(uri.getScheme())) {
+                    if (!Files.exists(Paths.get(uri))) {
+                        //resolved file does not exist, warn and let's continue with original systemId
+                        errorReceiver.warning(null, Messages.format(
+                                Messages.DOMFOREST_CATALOG_INVALID_ENTRY, is.getSystemId(), systemId));
+                        is = new InputSource(systemId);
+                    }
+                }
+            } catch (URISyntaxException ex) {
+                //ignore, let it be handled by parser as is
+            }
+        }
         // but we still use the original system Id as the key.
         return parse( systemId, is, root );
     }
diff --git a/jaxb-ri/xjc/src/main/java/com/sun/tools/xjc/reader/internalizer/Messages.java b/jaxb-ri/xjc/src/main/java/com/sun/tools/xjc/reader/internalizer/Messages.java
index 8609cbf..b75e82c 100644
--- a/jaxb-ri/xjc/src/main/java/com/sun/tools/xjc/reader/internalizer/Messages.java
+++ b/jaxb-ri/xjc/src/main/java/com/sun/tools/xjc/reader/internalizer/Messages.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -66,5 +66,7 @@
         "ERR_GENERAL_SCHEMA_CORRECTNESS_ERROR";
     static final String DOMFOREST_INPUTSOURCE_IOEXCEPTION = // arg:2
         "DOMFOREST_INPUTSOURCE_IOEXCEPTION";
+    static final String DOMFOREST_CATALOG_INVALID_ENTRY = // arg:2
+        "DOMFOREST_CATALOG_INVALID_ENTRY";
 
 }
diff --git a/jaxb-ri/xjc/src/main/resources/com/sun/tools/xjc/reader/internalizer/MessageBundle.properties b/jaxb-ri/xjc/src/main/resources/com/sun/tools/xjc/reader/internalizer/MessageBundle.properties
index a2a41f4..f5d5d9e 100644
--- a/jaxb-ri/xjc/src/main/resources/com/sun/tools/xjc/reader/internalizer/MessageBundle.properties
+++ b/jaxb-ri/xjc/src/main/resources/com/sun/tools/xjc/reader/internalizer/MessageBundle.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
 #
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -88,3 +88,6 @@
 
 DOMFOREST_INPUTSOURCE_IOEXCEPTION = \
     IOException thrown when processing "{0}". Exception: {1}.
+
+DOMFOREST_CATALOG_INVALID_ENTRY = \
+    Catalog points to non-existent resource: "{0}". Trying to reach "{1}" directly.