From 51449563338833c991c742e20a143a3fda27782c Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Fri, 3 Sep 2021 14:03:43 +0200 Subject: [PATCH 1/3] Bug Report: ModelValidationException when resource class and its interface both have @Path annotation Signed-off-by: Jorge Bescos Gascon --- .../model/RuntimeResourceModelValidator.java | 17 ++- .../tests/e2e/server/Issue4780Test.java | 118 ++++++++++++++++++ 2 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Test.java diff --git a/core-server/src/main/java/org/glassfish/jersey/server/model/RuntimeResourceModelValidator.java b/core-server/src/main/java/org/glassfish/jersey/server/model/RuntimeResourceModelValidator.java index fc935b09e3..2001233a94 100644 --- a/core-server/src/main/java/org/glassfish/jersey/server/model/RuntimeResourceModelValidator.java +++ b/core-server/src/main/java/org/glassfish/jersey/server/model/RuntimeResourceModelValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -103,9 +103,14 @@ private void checkIntersectingMediaTypes( } if (consumesFails && producesFails) { - // fatal - Errors.fatal(runtimeResource, LocalizationMessages.AMBIGUOUS_FATAL_RMS(httpMethod, m1.getInvocable() - .getHandlingMethod(), m2.getInvocable().getHandlingMethod(), runtimeResource.getRegex())); + boolean interfaceM1 = isInterface(m1); + boolean interfaceM2 = isInterface(m2); + // Fails when both are interfaces or both are not interfaces + if (interfaceM1 == interfaceM2) { + // fatal + Errors.fatal(runtimeResource, LocalizationMessages.AMBIGUOUS_FATAL_RMS(httpMethod, m1.getInvocable() + .getHandlingMethod(), m2.getInvocable().getHandlingMethod(), runtimeResource.getRegex())); + } } else if ((producesFails && consumesOnlyIntersects) || (consumesFails && producesOnlyIntersects) || (consumesOnlyIntersects && producesOnlyIntersects)) { @@ -122,6 +127,10 @@ private void checkIntersectingMediaTypes( } } + private boolean isInterface(ResourceMethod m1) { + return m1.getData().getInvocable().getHandler().getHandlerClass().isInterface(); + } + private static final List StarTypeList = Arrays.asList(new MediaType("*", "*")); private List getEffectiveInputTypes(final ResourceMethod resourceMethod) { diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Test.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Test.java new file mode 100644 index 0000000000..846789b8b8 --- /dev/null +++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Test.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + + +package org.glassfish.jersey.tests.e2e.server; + +import static org.junit.Assert.assertEquals; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.model.ModelValidationException; +import org.glassfish.jersey.test.JerseyTest; +import org.junit.Test; + +public class Issue4780Test { + + // 1 interface and 1 implementation having same @Path + @Test + public void resource1() throws Exception { + JerseyTest test = new JerseyTest(new ResourceConfig(Resource1_1.class, IResource1_2.class)) {}; + try { + test.setUp(); + Response response = test.target().path("/resource1").request().get(); + response.bufferEntity(); + assertEquals(response.readEntity(String.class), 200, response.getStatus()); + } finally { + test.tearDown(); + } + } + + // 2 interfaces having same @Path + @Test(expected = ModelValidationException.class) + public void resource2() throws Exception { + JerseyTest test = new JerseyTest(new ResourceConfig(IResource2_1.class, IResource2_2.class)) {}; + try { + test.setUp(); + } finally { + test.tearDown(); + } + } + + // 2 classes having same @Path + @Test(expected = ModelValidationException.class) + public void resource3() throws Exception { + JerseyTest test = new JerseyTest(new ResourceConfig(Resource3_1.class, Resource3_2.class)) {}; + try { + test.setUp(); + } finally { + test.tearDown(); + } + } + + @Path("") + public static class Resource1_1 implements IResource1_2 { + @GET + @Path("/resource1") + @Override + public String get() { + return ""; + } + } + + @Path("") + public static interface IResource1_2 { + @GET + @Path("/resource1") + String get(); + } + + @Path("") + public static interface IResource2_1 { + @GET + @Path("/resource2") + String get(); + } + + @Path("") + public static interface IResource2_2 { + @GET + @Path("/resource2") + String get(); + } + + @Path("") + public static class Resource3_1 { + @GET + @Path("/resource3") + public String get() { + return ""; + } + } + + @Path("") + public static class Resource3_2 { + @GET + @Path("/resource3") + public String get() { + return ""; + } + } + +} From 3974a96f051ea2169489e94c27c1036057d0e06e Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Mon, 6 Sep 2021 10:18:22 +0200 Subject: [PATCH 2/3] Split test in 3 Signed-off-by: Jorge Bescos Gascon --- .../e2e/server/Issue4780Resource1Test.java | 63 +++++++++++++++++++ .../e2e/server/Issue4780Resource2Test.java | 55 ++++++++++++++++ ...0Test.java => Issue4780Resource3Test.java} | 61 +----------------- 3 files changed, 119 insertions(+), 60 deletions(-) create mode 100644 tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource1Test.java create mode 100644 tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource2Test.java rename tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/{Issue4780Test.java => Issue4780Resource3Test.java} (51%) diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource1Test.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource1Test.java new file mode 100644 index 0000000000..01ca2e4f18 --- /dev/null +++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource1Test.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + + +package org.glassfish.jersey.tests.e2e.server; + +import static org.junit.Assert.assertEquals; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Response; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.JerseyTest; +import org.junit.Test; + +public class Issue4780Resource1Test extends JerseyTest { + + // 1 interface and 1 implementation having same @Path + @Test + public void resource1() throws Exception { + Response response = target().path("/resource1").request().get(); + response.bufferEntity(); + assertEquals(response.readEntity(String.class), 200, response.getStatus()); + } + + @Override + protected Application configure() { + return new ResourceConfig(Resource1_1.class, IResource1_2.class); + } + + @Path("") + public static class Resource1_1 implements IResource1_2 { + @GET + @Path("/resource1") + @Override + public String get() { + return ""; + } + } + + @Path("") + public static interface IResource1_2 { + @GET + @Path("/resource1") + String get(); + } + +} diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource2Test.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource2Test.java new file mode 100644 index 0000000000..3e3af13c64 --- /dev/null +++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource2Test.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + + +package org.glassfish.jersey.tests.e2e.server; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.model.ModelValidationException; +import org.glassfish.jersey.test.JerseyTest; +import org.junit.Test; + +public class Issue4780Resource2Test { + + // 2 interfaces having same @Path + @Test(expected = ModelValidationException.class) + public void resource2() throws Exception { + JerseyTest test = new JerseyTest(new ResourceConfig(IResource2_1.class, IResource2_2.class)) {}; + try { + test.setUp(); + } finally { + test.tearDown(); + } + } + + @Path("") + public static interface IResource2_1 { + @GET + @Path("/resource2") + String get(); + } + + @Path("") + public static interface IResource2_2 { + @GET + @Path("/resource2") + String get(); + } + +} diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Test.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource3Test.java similarity index 51% rename from tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Test.java rename to tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource3Test.java index 846789b8b8..6a88d11e71 100644 --- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Test.java +++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource3Test.java @@ -17,43 +17,15 @@ package org.glassfish.jersey.tests.e2e.server; -import static org.junit.Assert.assertEquals; - import javax.ws.rs.GET; import javax.ws.rs.Path; -import javax.ws.rs.core.Response; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.model.ModelValidationException; import org.glassfish.jersey.test.JerseyTest; import org.junit.Test; -public class Issue4780Test { - - // 1 interface and 1 implementation having same @Path - @Test - public void resource1() throws Exception { - JerseyTest test = new JerseyTest(new ResourceConfig(Resource1_1.class, IResource1_2.class)) {}; - try { - test.setUp(); - Response response = test.target().path("/resource1").request().get(); - response.bufferEntity(); - assertEquals(response.readEntity(String.class), 200, response.getStatus()); - } finally { - test.tearDown(); - } - } - - // 2 interfaces having same @Path - @Test(expected = ModelValidationException.class) - public void resource2() throws Exception { - JerseyTest test = new JerseyTest(new ResourceConfig(IResource2_1.class, IResource2_2.class)) {}; - try { - test.setUp(); - } finally { - test.tearDown(); - } - } +public class Issue4780Resource3Test { // 2 classes having same @Path @Test(expected = ModelValidationException.class) @@ -66,37 +38,6 @@ public void resource3() throws Exception { } } - @Path("") - public static class Resource1_1 implements IResource1_2 { - @GET - @Path("/resource1") - @Override - public String get() { - return ""; - } - } - - @Path("") - public static interface IResource1_2 { - @GET - @Path("/resource1") - String get(); - } - - @Path("") - public static interface IResource2_1 { - @GET - @Path("/resource2") - String get(); - } - - @Path("") - public static interface IResource2_2 { - @GET - @Path("/resource2") - String get(); - } - @Path("") public static class Resource3_1 { @GET From 5d546f04465c8295434a937ceb7ab2ea7da541d5 Mon Sep 17 00:00:00 2001 From: jbescos Date: Wed, 16 Nov 2022 14:43:10 +0100 Subject: [PATCH 3/3] Update to junit5 Signed-off-by: Jorge Bescos Gascon --- .../e2e/server/Issue4780Resource1Test.java | 10 ++++---- .../e2e/server/Issue4780Resource2Test.java | 24 +++++++++++-------- .../e2e/server/Issue4780Resource3Test.java | 24 +++++++++++-------- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource1Test.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource1Test.java index 01ca2e4f18..e474d243e5 100644 --- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource1Test.java +++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource1Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -14,10 +14,9 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 */ - package org.glassfish.jersey.tests.e2e.server; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -26,7 +25,7 @@ import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class Issue4780Resource1Test extends JerseyTest { @@ -34,8 +33,7 @@ public class Issue4780Resource1Test extends JerseyTest { @Test public void resource1() throws Exception { Response response = target().path("/resource1").request().get(); - response.bufferEntity(); - assertEquals(response.readEntity(String.class), 200, response.getStatus()); + assertEquals(200, response.getStatus()); } @Override diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource2Test.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource2Test.java index 3e3af13c64..f1bdeed5f3 100644 --- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource2Test.java +++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource2Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -14,28 +14,32 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 */ - package org.glassfish.jersey.tests.e2e.server; +import static org.junit.jupiter.api.Assertions.assertThrows; + import javax.ws.rs.GET; import javax.ws.rs.Path; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.model.ModelValidationException; import org.glassfish.jersey.test.JerseyTest; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class Issue4780Resource2Test { // 2 interfaces having same @Path - @Test(expected = ModelValidationException.class) + @Test public void resource2() throws Exception { - JerseyTest test = new JerseyTest(new ResourceConfig(IResource2_1.class, IResource2_2.class)) {}; - try { - test.setUp(); - } finally { - test.tearDown(); - } + assertThrows(ModelValidationException.class, () -> { + JerseyTest test = new JerseyTest(new ResourceConfig(IResource2_1.class, IResource2_2.class)) { + }; + try { + test.setUp(); + } finally { + test.tearDown(); + } + }); } @Path("") diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource3Test.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource3Test.java index 6a88d11e71..fe6868b895 100644 --- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource3Test.java +++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4780Resource3Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -14,28 +14,32 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 */ - package org.glassfish.jersey.tests.e2e.server; +import static org.junit.jupiter.api.Assertions.assertThrows; + import javax.ws.rs.GET; import javax.ws.rs.Path; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.model.ModelValidationException; import org.glassfish.jersey.test.JerseyTest; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class Issue4780Resource3Test { // 2 classes having same @Path - @Test(expected = ModelValidationException.class) + @Test public void resource3() throws Exception { - JerseyTest test = new JerseyTest(new ResourceConfig(Resource3_1.class, Resource3_2.class)) {}; - try { - test.setUp(); - } finally { - test.tearDown(); - } + assertThrows(ModelValidationException.class, () -> { + JerseyTest test = new JerseyTest(new ResourceConfig(Resource3_1.class, Resource3_2.class)) { + }; + try { + test.setUp(); + } finally { + test.tearDown(); + } + }); } @Path("")