CXF-8180/CXF-8181 - UnsupportedOperationException in AbstractEndpointFactory / CXFNonSpringJaxrsServlet Feature registration fails via javax.ws.rs.Application
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java
index 321a5d4..c8f1647 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java
@@ -165,7 +165,7 @@
setExtensions(bean, servletConfig);
List<? extends Feature> features = getFeatures(servletConfig, splitChar);
- bean.setFeatures(features);
+ bean.getFeatures().addAll(features);
bean.create();
}
@@ -190,9 +190,12 @@
CastUtils.cast((Map<?, ?>)parseMapSequence(servletConfig.getInitParameter(EXTENSIONS_PARAM))));
bean.setLanguageMappings(
CastUtils.cast((Map<?, ?>)parseMapSequence(servletConfig.getInitParameter(LANGUAGES_PARAM))));
- bean.setProperties(CastUtils.cast(
+ Map<String, Object> properties = CastUtils.cast(
parseMapSequence(servletConfig.getInitParameter(PROPERTIES_PARAM)),
- String.class, Object.class));
+ String.class, Object.class);
+ if (properties != null) {
+ bean.getProperties(true).putAll(properties);
+ }
}
protected void setAllInterceptors(JAXRSServerFactoryBean bean, ServletConfig servletConfig,
@@ -527,7 +530,7 @@
List<?> providers = getProviders(servletConfig, splitChar);
bean.setProviders(providers);
List<? extends Feature> features = getFeatures(servletConfig, splitChar);
- bean.setFeatures(features);
+ bean.getFeatures().addAll(features);
bean.setBus(getBus());
bean.setApplicationInfo(providerApp);
@@ -560,7 +563,7 @@
List<?> providers = getProviders(servletConfig, splitChar);
bean.setProviders(providers);
List<? extends Feature> features = getFeatures(servletConfig, splitChar);
- bean.setFeatures(features);
+ bean.getFeatures().addAll(features);
bean.setBus(getBus());
bean.setApplication(getApplication());
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
index 471fa85..10119d7 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
@@ -944,7 +944,7 @@
bean.setStaticSubresourceResolution(staticSubresourceResolution);
bean.setResourceClasses(resourceClasses);
bean.setProviders(providers);
- bean.setFeatures(features);
+ bean.getFeatures().addAll(features);
for (Map.Entry<Class<?>, ResourceProvider> entry : map.entrySet()) {
bean.setResourceProvider(entry.getKey(), entry.getValue());
}
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplicationNonSpring.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplicationNonSpring.java
new file mode 100644
index 0000000..1d3c4ed
--- /dev/null
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookApplicationNonSpring.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.jaxrs;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.cxf.jaxrs.openapi.OpenApiFeature;
+
+@ApplicationPath("/")
+@GlobalNameBinding
+public class BookApplicationNonSpring extends Application {
+
+ private String defaultName;
+ private long defaultId;
+ @Context
+ private UriInfo uriInfo;
+
+ @Override
+ public Set<Class<?>> getClasses() {
+ Set<Class<?>> classes = new HashSet<>();
+ classes.add(org.apache.cxf.systest.jaxrs.BookStore.class);
+ return classes;
+ }
+
+ @Override
+ public Set<Object> getSingletons() {
+ Set<Object> classes = new HashSet<>();
+ org.apache.cxf.systest.jaxrs.BookStore store =
+ new org.apache.cxf.systest.jaxrs.BookStore(uriInfo);
+ store.setDefaultNameAndId(defaultName, defaultId);
+ classes.add(store);
+ BookExceptionMapper mapper = new org.apache.cxf.systest.jaxrs.BookExceptionMapper();
+ mapper.setToHandle(true);
+ classes.add(mapper);
+ classes.add(new OpenApiFeature());
+ return classes;
+ }
+
+
+ @Override
+ public Map<String, Object> getProperties() {
+ return Collections.<String, Object>singletonMap("book", "cxf");
+ }
+
+ public void setDefaultName(String name) {
+ defaultName = name;
+ }
+
+ public void setDefaultId(List<String> ids) {
+ StringBuilder sb = new StringBuilder();
+ for (String id : ids) {
+ sb.append(id);
+ }
+ defaultId = Long.valueOf(sb.toString());
+ }
+
+}
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreNonSpring.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreNonSpring.java
new file mode 100644
index 0000000..48ec617
--- /dev/null
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreNonSpring.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.jaxrs;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+
+@Path("/bookstore")
+public class BookStoreNonSpring {
+
+ @GET
+ @Path("/")
+ public Book getBookRoot() {
+ Book book = new Book();
+ book.setName("root");
+ book.setId(124L);
+ return book;
+ }
+
+}
\ No newline at end of file
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreOpenAPI.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreOpenAPI.java
new file mode 100644
index 0000000..e87643f
--- /dev/null
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreOpenAPI.java
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.jaxrs;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+
+import org.apache.cxf.feature.Features;
+
+@Path("/bookstore")
+@Features(features = "org.apache.cxf.jaxrs.openapi.OpenApiFeature")
+public class BookStoreOpenAPI {
+
+ @GET
+ @Path("/")
+ public Book getBookRoot() {
+ Book book = new Book();
+ book.setName("root");
+ book.setId(124L);
+ return book;
+ }
+
+}
\ No newline at end of file
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSNonSpringJaxrsServletTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSNonSpringJaxrsServletTest.java
index a7bcc6d..b60c258 100644
--- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSNonSpringJaxrsServletTest.java
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSNonSpringJaxrsServletTest.java
@@ -19,6 +19,8 @@
package org.apache.cxf.systest.jaxrs;
+import javax.ws.rs.core.Response;
+
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.model.AbstractResourceInfo;
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
@@ -34,23 +36,44 @@
*/
public class JAXRSNonSpringJaxrsServletTest extends AbstractBusClientServerTestBase {
public static final String PORT = NonSpringJaxrsServletBookServer.PORT;
- public static final String PORT2 = allocatePort(JAXRSNonSpringJaxrsServletTest.class);
+ public static final String PORT2 = NonSpringJaxrsServletBookServer2.PORT;
@BeforeClass
public static void startServers() throws Exception {
AbstractResourceInfo.clearAllMaps();
assertTrue("server did not launch correctly",
launchServer(NonSpringJaxrsServletBookServer.class, true));
+ assertTrue("server did not launch correctly",
+ launchServer(NonSpringJaxrsServletBookServer2.class, true));
createStaticBus();
}
@Test
- public void testGetBookRoot() throws Exception {
+ public void testFeatureOnResourceClass() throws Exception {
String address = "http://localhost:" + PORT + "/bookstore/;JSESSIONID=xxx";
WebClient wc = WebClient.create(address);
Book book = wc.get(Book.class);
assertEquals(124L, book.getId());
assertEquals("root", book.getName());
+
+ // Check OpenAPI feature is working correctly
+ wc = WebClient.create("http://localhost:" + PORT + "/openapi.json");
+ Response openAPIResponse = wc.get();
+ assertEquals(200, openAPIResponse.getStatus());
+ }
+
+ @Test
+ public void testFeatureOnResourceClassUsingApplication() throws Exception {
+ String address = "http://localhost:" + PORT2 + "/bookstore/;JSESSIONID=xxx";
+ WebClient wc = WebClient.create(address);
+ Book book = wc.get(Book.class);
+ assertEquals(124L, book.getId());
+ assertEquals("root", book.getName());
+
+ // Check OpenAPI feature is working correctly
+ wc = WebClient.create("http://localhost:" + PORT2 + "/openapi.json");
+ Response openAPIResponse = wc.get();
+ assertEquals(200, openAPIResponse.getStatus());
}
}
\ No newline at end of file
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/NonSpringJaxrsServletBookServer.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/NonSpringJaxrsServletBookServer.java
index 7ff828e..adaf782 100644
--- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/NonSpringJaxrsServletBookServer.java
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/NonSpringJaxrsServletBookServer.java
@@ -33,7 +33,8 @@
protected void run() {
server = new org.eclipse.jetty.server.Server(Integer.parseInt(PORT));
- final ServletHolder servletHolder = new ServletHolder(new CXFNonSpringJaxrsServlet(new BookStore()));
+ final ServletHolder servletHolder =
+ new ServletHolder(new CXFNonSpringJaxrsServlet(new BookStoreOpenAPI()));
final ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
context.addServlet(servletHolder, "/*");
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/NonSpringJaxrsServletBookServer2.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/NonSpringJaxrsServletBookServer2.java
new file mode 100644
index 0000000..fc1b609
--- /dev/null
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/NonSpringJaxrsServletBookServer2.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.jaxrs;
+
+import org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+
+public class NonSpringJaxrsServletBookServer2 extends AbstractBusTestServerBase {
+ public static final String PORT = allocatePort(NonSpringJaxrsServletBookServer2.class);
+ private org.eclipse.jetty.server.Server server;
+
+ protected void run() {
+ server = new org.eclipse.jetty.server.Server(Integer.parseInt(PORT));
+
+ final ServletHolder servletHolder =
+ new ServletHolder(new CXFNonSpringJaxrsServlet(new BookApplicationNonSpring()));
+ final ServletContextHandler context = new ServletContextHandler();
+ context.setContextPath("/");
+ context.addServlet(servletHolder, "/*");
+ //servletHolder.setInitParameter("jaxrs.serviceClasses", BookStore.class.getName());
+
+ server.setHandler(context);
+ try {
+ server.start();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void tearDown() throws Exception {
+ if (server != null) {
+ server.stop();
+ server.destroy();
+ server = null;
+ }
+ }
+
+ public static void main(String[] args) {
+ try {
+ NonSpringJaxrsServletBookServer2 s = new NonSpringJaxrsServletBookServer2();
+ s.start();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ System.exit(-1);
+ } finally {
+ System.out.println("done!");
+ }
+ }
+}