Skip to content

Commit f5227f9

Browse files
Fix AXIS2-6053: Add diagnostic hints for unresolved attribute ref= in schema validation
When a schema uses xs:attribute ref= to reference an attribute from an external namespace (e.g., xmime:contentType) and the referenced schema cannot be resolved, the validator produces a cryptic cvc-complex-type.3.2.2 error. This change detects that error code and appends an actionable hint explaining the likely cause and remediation. Also improves SchemaFactoryErrorHandler to log warnings with full exception context, making unresolvable import warnings visible for diagnosis. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 90764ed commit f5227f9

4 files changed

Lines changed: 78 additions & 3 deletions

File tree

modules/schema-validation/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@
4949
<artifactId>axis2-kernel</artifactId>
5050
<version>${project.version}</version>
5151
</dependency>
52+
<dependency>
53+
<groupId>org.junit.jupiter</groupId>
54+
<artifactId>junit-jupiter</artifactId>
55+
<scope>test</scope>
56+
</dependency>
57+
<dependency>
58+
<groupId>org.assertj</groupId>
59+
<artifactId>assertj-core</artifactId>
60+
<scope>test</scope>
61+
</dependency>
5262
</dependencies>
5363

5464
<build>

modules/schema-validation/src/main/java/org/apache/axis2/validation/SchemaFactoryErrorHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ final class SchemaFactoryErrorHandler implements ErrorHandler {
2929

3030
@Override
3131
public void warning(SAXParseException exception) throws SAXException {
32-
log.warn(exception.getMessage());
32+
log.warn("Schema compilation warning: " + exception.getMessage(), exception);
3333
}
3434

3535
@Override

modules/schema-validation/src/main/java/org/apache/axis2/validation/SchemaValidationHandler.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,29 @@ public InvocationResponse invoke(MessageContext msgContext) throws AxisFault {
7171
try {
7272
schema = schemaFactory.newSchema(schemaSources.toArray(new Source[schemaSources.size()]));
7373
} catch (SAXException ex) {
74-
throw new AxisFault("Failed to compile schemas", ex);
74+
throw new AxisFault("Failed to compile schemas: " + ex.getMessage()
75+
+ appendRefHint(ex), ex);
7576
}
7677
try {
7778
schema.newValidator().validate(msgContext.getEnvelope().getBody().getFirstElement().getSAXSource(true));
7879
} catch (SAXException ex) {
79-
throw new AxisFault("Failed to validate message: " + ex.getMessage(), ex);
80+
throw new AxisFault("Failed to validate message: " + ex.getMessage()
81+
+ appendRefHint(ex), ex);
8082
} catch (OMException | IOException ex) {
8183
throw new AxisFault("Failed to validate message", ex);
8284
}
8385
return InvocationResponse.CONTINUE;
8486
}
87+
88+
static String appendRefHint(SAXException ex) {
89+
String msg = ex.getMessage();
90+
if (msg != null && msg.contains("cvc-complex-type.3.2.2")) {
91+
return ". This may be caused by a schema using xs:attribute ref= to reference"
92+
+ " an attribute from an external namespace (e.g., xmime:contentType)"
93+
+ " whose schema was not imported or could not be resolved."
94+
+ " Consider defining the attribute inline instead of using ref=,"
95+
+ " or ensure the referenced schema is accessible.";
96+
}
97+
return "";
98+
}
8599
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.axis2.validation;
20+
21+
import static org.assertj.core.api.Assertions.assertThat;
22+
23+
import org.junit.jupiter.api.Test;
24+
import org.xml.sax.SAXException;
25+
26+
public class SchemaValidationHandlerTest {
27+
28+
@Test
29+
public void testAppendRefHintForCvcComplexType322() {
30+
SAXException ex = new SAXException(
31+
"cvc-complex-type.3.2.2: Attribute 'contentType' is not allowed to appear in element 'foo'");
32+
String hint = SchemaValidationHandler.appendRefHint(ex);
33+
assertThat(hint).contains("xs:attribute ref=");
34+
assertThat(hint).contains("xmime:contentType");
35+
assertThat(hint).contains("not imported or could not be resolved");
36+
}
37+
38+
@Test
39+
public void testAppendRefHintReturnsEmptyForOtherErrors() {
40+
SAXException ex = new SAXException("cvc-type.3.1.3: some other validation error");
41+
String hint = SchemaValidationHandler.appendRefHint(ex);
42+
assertThat(hint).isEmpty();
43+
}
44+
45+
@Test
46+
public void testAppendRefHintHandlesNullMessage() {
47+
SAXException ex = new SAXException((String) null);
48+
String hint = SchemaValidationHandler.appendRefHint(ex);
49+
assertThat(hint).isEmpty();
50+
}
51+
}

0 commit comments

Comments
 (0)