Skip to content

Commit 470ce25

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 470ce25

File tree

2 files changed

+119
-4
lines changed

2 files changed

+119
-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: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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+
test.setUp();
38+
Response response = test.target().path("/resource1").request().get();
39+
assertEquals(200, response.getStatus());
40+
test.tearDown();
41+
}
42+
43+
// 2 interfaces having same @Path
44+
@Test(expected = ModelValidationException.class)
45+
public void resource2() throws Exception {
46+
JerseyTest test = new JerseyTest(new ResourceConfig(IResource2_1.class, IResource2_2.class)) {};
47+
test.setUp();
48+
}
49+
50+
// 2 classes having same @Path
51+
@Test(expected = ModelValidationException.class)
52+
public void resource3() throws Exception {
53+
JerseyTest test = new JerseyTest(new ResourceConfig(Resource3_1.class, Resource3_2.class)) {};
54+
test.setUp();
55+
}
56+
57+
@Path("")
58+
public static class Resource1_1 implements IResource1_2 {
59+
@GET
60+
@Path("/resource1")
61+
@Override
62+
public String get() {
63+
return "";
64+
}
65+
}
66+
67+
@Path("")
68+
public static interface IResource1_2 {
69+
@GET
70+
@Path("/resource1")
71+
String get();
72+
}
73+
74+
@Path("")
75+
public static interface IResource2_1 {
76+
@GET
77+
@Path("/resource2")
78+
String get();
79+
}
80+
81+
@Path("")
82+
public static interface IResource2_2 {
83+
@GET
84+
@Path("/resource2")
85+
String get();
86+
}
87+
88+
@Path("")
89+
public static class Resource3_1 {
90+
@GET
91+
@Path("/resource3")
92+
public String get() {
93+
return "";
94+
}
95+
}
96+
97+
@Path("")
98+
public static class Resource3_2 {
99+
@GET
100+
@Path("/resource3")
101+
public String get() {
102+
return "";
103+
}
104+
}
105+
106+
}

0 commit comments

Comments
 (0)