Skip to content

Commit 5144956

Browse files
committed
Bug Report: ModelValidationException when resource class and its interface both have @path annotation
Signed-off-by: Jorge Bescos Gascon <[email protected]>
1 parent 3d131db commit 5144956

File tree

2 files changed

+131
-4
lines changed

2 files changed

+131
-4
lines changed

core-server/src/main/java/org/glassfish/jersey/server/model/RuntimeResourceModelValidator.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -103,9 +103,14 @@ private void checkIntersectingMediaTypes(
103103
}
104104

105105
if (consumesFails && producesFails) {
106-
// fatal
107-
Errors.fatal(runtimeResource, LocalizationMessages.AMBIGUOUS_FATAL_RMS(httpMethod, m1.getInvocable()
108-
.getHandlingMethod(), m2.getInvocable().getHandlingMethod(), runtimeResource.getRegex()));
106+
boolean interfaceM1 = isInterface(m1);
107+
boolean interfaceM2 = isInterface(m2);
108+
// Fails when both are interfaces or both are not interfaces
109+
if (interfaceM1 == interfaceM2) {
110+
// fatal
111+
Errors.fatal(runtimeResource, LocalizationMessages.AMBIGUOUS_FATAL_RMS(httpMethod, m1.getInvocable()
112+
.getHandlingMethod(), m2.getInvocable().getHandlingMethod(), runtimeResource.getRegex()));
113+
}
109114
} else if ((producesFails && consumesOnlyIntersects)
110115
|| (consumesFails && producesOnlyIntersects)
111116
|| (consumesOnlyIntersects && producesOnlyIntersects)) {
@@ -122,6 +127,10 @@ private void checkIntersectingMediaTypes(
122127
}
123128
}
124129

130+
private boolean isInterface(ResourceMethod m1) {
131+
return m1.getData().getInvocable().getHandler().getHandlerClass().isInterface();
132+
}
133+
125134
private static final List<MediaType> StarTypeList = Arrays.asList(new MediaType("*", "*"));
126135

127136
private List<MediaType> getEffectiveInputTypes(final ResourceMethod resourceMethod) {
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
18+
package org.glassfish.jersey.tests.e2e.server;
19+
20+
import static org.junit.Assert.assertEquals;
21+
22+
import javax.ws.rs.GET;
23+
import javax.ws.rs.Path;
24+
import javax.ws.rs.core.Response;
25+
26+
import org.glassfish.jersey.server.ResourceConfig;
27+
import org.glassfish.jersey.server.model.ModelValidationException;
28+
import org.glassfish.jersey.test.JerseyTest;
29+
import org.junit.Test;
30+
31+
public class Issue4780Test {
32+
33+
// 1 interface and 1 implementation having same @Path
34+
@Test
35+
public void resource1() throws Exception {
36+
JerseyTest test = new JerseyTest(new ResourceConfig(Resource1_1.class, IResource1_2.class)) {};
37+
try {
38+
test.setUp();
39+
Response response = test.target().path("/resource1").request().get();
40+
response.bufferEntity();
41+
assertEquals(response.readEntity(String.class), 200, response.getStatus());
42+
} finally {
43+
test.tearDown();
44+
}
45+
}
46+
47+
// 2 interfaces having same @Path
48+
@Test(expected = ModelValidationException.class)
49+
public void resource2() throws Exception {
50+
JerseyTest test = new JerseyTest(new ResourceConfig(IResource2_1.class, IResource2_2.class)) {};
51+
try {
52+
test.setUp();
53+
} finally {
54+
test.tearDown();
55+
}
56+
}
57+
58+
// 2 classes having same @Path
59+
@Test(expected = ModelValidationException.class)
60+
public void resource3() throws Exception {
61+
JerseyTest test = new JerseyTest(new ResourceConfig(Resource3_1.class, Resource3_2.class)) {};
62+
try {
63+
test.setUp();
64+
} finally {
65+
test.tearDown();
66+
}
67+
}
68+
69+
@Path("")
70+
public static class Resource1_1 implements IResource1_2 {
71+
@GET
72+
@Path("/resource1")
73+
@Override
74+
public String get() {
75+
return "";
76+
}
77+
}
78+
79+
@Path("")
80+
public static interface IResource1_2 {
81+
@GET
82+
@Path("/resource1")
83+
String get();
84+
}
85+
86+
@Path("")
87+
public static interface IResource2_1 {
88+
@GET
89+
@Path("/resource2")
90+
String get();
91+
}
92+
93+
@Path("")
94+
public static interface IResource2_2 {
95+
@GET
96+
@Path("/resource2")
97+
String get();
98+
}
99+
100+
@Path("")
101+
public static class Resource3_1 {
102+
@GET
103+
@Path("/resource3")
104+
public String get() {
105+
return "";
106+
}
107+
}
108+
109+
@Path("")
110+
public static class Resource3_2 {
111+
@GET
112+
@Path("/resource3")
113+
public String get() {
114+
return "";
115+
}
116+
}
117+
118+
}

0 commit comments

Comments
 (0)