This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch coheigea/error
in repository https://gitbox.apache.org/repos/asf/cxf-xjc-utils.git

commit 2b10d80927b2bd82eb82fc3173027a726160fdab
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Mon Oct 26 14:46:11 2026 +0000

    Report a missing classpath: catalog resource clearly in cxf-xjc-plugin
---
 .../apache/cxf/maven_plugin/XSDToJavaRunner.java   | 11 +++-
 .../cxf/maven_plugin/XSDToJavaRunnerTest.java      | 64 ++++++++++++++++++++++
 2 files changed, 74 insertions(+), 1 deletion(-)

diff --git 
a/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/XSDToJavaRunner.java 
b/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/XSDToJavaRunner.java
index 8526e31..6a41f28 100644
--- 
a/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/XSDToJavaRunner.java
+++ 
b/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/XSDToJavaRunner.java
@@ -20,6 +20,7 @@
 package org.apache.cxf.maven_plugin;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
@@ -186,7 +187,15 @@ public class XSDToJavaRunner {
                     try {
                         final URL url;
                         if (resolved.startsWith("classpath:")) {
-                            url = 
loader.getResource(resolved.substring("classpath:".length()));
+                            String resource = 
resolved.substring("classpath:".length());
+                            url = loader.getResource(resource);
+                            if (url == null) {
+                                // say what is missing, then fall back to the 
default resolution
+                                listener.warning(xsdFile, new 
FileNotFoundException("Resource " + resource
+                                    + ", which the catalog maps "
+                                    + (systemId != null ? systemId : publicId) 
+ " to, is not on the classpath"));
+                                return null;
+                            }
                             iSource.setSystemId(url.toExternalForm());
                         } else {
                             url = new URL(resolved);
diff --git 
a/cxf-xjc-plugin/src/test/java/org/apache/cxf/maven_plugin/XSDToJavaRunnerTest.java
 
b/cxf-xjc-plugin/src/test/java/org/apache/cxf/maven_plugin/XSDToJavaRunnerTest.java
index da142ed..8b292ee 100644
--- 
a/cxf-xjc-plugin/src/test/java/org/apache/cxf/maven_plugin/XSDToJavaRunnerTest.java
+++ 
b/cxf-xjc-plugin/src/test/java/org/apache/cxf/maven_plugin/XSDToJavaRunnerTest.java
@@ -20,7 +20,11 @@
 package org.apache.cxf.maven_plugin;
 
 import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 
 import org.sonatype.plexus.build.incremental.BuildContext;  
 
@@ -30,7 +34,10 @@ import org.junit.rules.TemporaryFolder;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 
 public class XSDToJavaRunnerTest {
     @Rule public TemporaryFolder outputFolder = new TemporaryFolder();
@@ -59,4 +66,61 @@ public class XSDToJavaRunnerTest {
         
         assertThat(listener.getFirstError(), is(nullValue()));
     }
+
+    /**
+     * Records the messages reported, instead of printing them.
+     */
+    private static final class RecordingBuildContext extends XJCBuildContext {
+        final List<String> messages = new ArrayList<>();
+
+        @Override
+        public void addMessage(File file, int line, int column, String 
message, int severity, Throwable cause) {
+            messages.add(message);
+        }
+    }
+
+    // compiles a schema importing namespace urn:imported, which the catalog 
maps to classpath:<resource>
+    private int compileWithClasspathCatalog(String resource, List<String> 
classpath,
+                                            RecordingBuildContext context) 
throws Exception {
+        File dir = outputFolder.newFolder();
+        File xsd = new File(dir, "main.xsd");
+        Files.write(xsd.toPath(), ("<xs:schema 
xmlns:xs='http://www.w3.org/2001/XMLSchema'"
+            + " xmlns:i='urn:imported' targetNamespace='urn:main'>"
+            + "<xs:import namespace='urn:imported' 
schemaLocation='imported.xsd'/>"
+            + "<xs:element name='root' 
type='i:T'/></xs:schema>").getBytes(StandardCharsets.UTF_8));
+        File catalog = new File(dir, "catalog.xml");
+        Files.write(catalog.toPath(), ("<catalog 
xmlns='urn:oasis:names:tc:entity:xmlns:xml:catalog'>"
+            + "<public publicId='urn:imported' uri='classpath:" + resource + 
"'/>"
+            + "</catalog>").getBytes(StandardCharsets.UTF_8));
+        File genDir = outputFolder.newFolder();
+        String[] args = {"-catalog", catalog.getAbsolutePath(), "-d", 
genDir.getAbsolutePath(), xsd.toURI().toString()};
+        return new XSDToJavaRunner(args, new XJCErrorListener(context), 
genDir, new ArrayList<>(classpath)).run();
+    }
+
+    @Test
+    public void testClasspathCatalogEntry() throws Exception {
+        File cpDir = outputFolder.newFolder();
+        Files.createDirectories(new File(cpDir, "imports").toPath());
+        Files.write(new File(cpDir, "imports/imported.xsd").toPath(),
+            ("<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' 
targetNamespace='urn:imported'>"
+            + "<xs:simpleType name='T'><xs:restriction 
base='xs:string'/></xs:simpleType></xs:schema>")
+            .getBytes(StandardCharsets.UTF_8));
+
+        RecordingBuildContext context = new RecordingBuildContext();
+        int rc = compileWithClasspathCatalog("imports/imported.xsd",
+                                             
Collections.singletonList(cpDir.getAbsolutePath()), context);
+        assertEquals(context.messages.toString(), 0, rc);
+    }
+
+    @Test
+    public void testClasspathCatalogEntryNotFound() throws Exception {
+        RecordingBuildContext context = new RecordingBuildContext();
+        // the import can then not be resolved, so the compile fails
+        compileWithClasspathCatalog("does/not/exist.xsd", 
Collections.<String>emptyList(), context);
+
+        String messages = context.messages.toString();
+        assertTrue(messages, messages.contains("Resource does/not/exist.xsd, 
which the catalog maps"));
+        assertTrue(messages, messages.contains("is not on the classpath"));
+        assertFalse(messages, messages.contains("NullPointerException"));
+    }
 }

Reply via email to