Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2024 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2025 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
Expand Down Expand Up @@ -50,24 +50,33 @@
public class DefaultJacksonJaxbJsonProvider extends JacksonJaxbJsonProvider {
private Configuration commonConfig;
private static final Logger LOGGER = Logger.getLogger(DefaultJacksonJaxbJsonProvider.class.getName());
private final boolean hasConfig;

@Inject
public DefaultJacksonJaxbJsonProvider(@Context Providers providers, @Context Configuration config) {
this(providers, config, DEFAULT_ANNOTATIONS);
}

//do not register JaxbAnnotationModule because it brakes default annotations processing
private static final String EXCLUDE_MODULE_NAME = "JaxbAnnotationModule";
private static final String[] EXCLUDE_MODULE_NAMES = {"JaxbAnnotationModule", "JakartaXmlBindAnnotationModule"};

public DefaultJacksonJaxbJsonProvider(Providers providers, Configuration config, Annotations... annotationsToUse) {
super(annotationsToUse);
this.commonConfig = config;
_providers = providers;

Object jaxrsFeatureBag = config.getProperty(JaxrsFeatureBag.JAXRS_FEATURE);
if (jaxrsFeatureBag != null && (JaxrsFeatureBag.class.isInstance(jaxrsFeatureBag))) {
((JaxrsFeatureBag) jaxrsFeatureBag).configureJaxrsFeatures(this);
boolean ex = true;
try {
Object jaxrsFeatureBag = config.getProperty(JaxrsFeatureBag.JAXRS_FEATURE);
if (jaxrsFeatureBag != null && (JaxrsFeatureBag.class.isInstance(jaxrsFeatureBag))) {
((JaxrsFeatureBag) jaxrsFeatureBag).configureJaxrsFeatures(this);
}
} catch (RuntimeException e) {
// ignore - not configured
LOGGER.fine(LocalizationMessages.ERROR_CONFIGURING(e.getMessage()));
ex = false;
}
hasConfig = ex;
}

@Override
Expand All @@ -82,7 +91,9 @@ protected ObjectMapper _locateMapperViaProvider(Class<?> type, MediaType mediaTy
@Override
protected JsonEndpointConfig _configForReading(ObjectReader reader, Annotation[] annotations) {
try {
updateFactoryConstraints(reader.getFactory());
if (hasConfig) {
updateFactoryConstraints(reader.getFactory());
}
} catch (Throwable t) {
// A Jackson 14 would throw NoSuchMethodError, ClassNotFoundException, NoClassDefFoundError or similar
// that should have been ignored
Expand All @@ -97,7 +108,7 @@ private void findAndRegisterModules() {
final ObjectMapper defaultMapper = _mapperConfig.getDefaultMapper();
final ObjectMapper mapper = _mapperConfig.getConfiguredMapper();

final List<Module> modules = filterModules();
final List<Module> modules = filterModules();

defaultMapper.registerModules(modules);
if (mapper != null) {
Expand All @@ -122,8 +133,9 @@ private List<Module> filterModules() {
LOGGER.warning(LocalizationMessages.ERROR_MODULES_NOT_LOADED(e.getMessage()));
return Collections.emptyList();
}

modules.removeIf(mod -> mod.getModuleName().contains(EXCLUDE_MODULE_NAME));
for (String exludeModuleName : EXCLUDE_MODULE_NAMES) {
modules.removeIf(mod -> mod.getModuleName().contains(exludeModuleName));
}

if (enabledModules != null && !enabledModules.isEmpty()) {
final List<String> enabledModulesList = Arrays.asList(enabledModules.split(","));
Expand Down Expand Up @@ -161,4 +173,4 @@ private void updateFactoryConstraints(JsonFactory jsonFactory) {
jsonFactory.setStreamReadConstraints(builder.build());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2023, 2024 Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2023, 2025 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
Expand All @@ -13,6 +13,7 @@
#
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
#
error.configuring=Error configuring the DefaultJacksonJaxbJsonProvider: {0}.
error.jackson.streamreadconstraints=Error setting StreamReadConstraints: {0}. Possibly not Jackson 2.15?
error.jackson.streamreadconstraints218=Error setting StreamReadConstraints: {0}. Possibly not Jackson 2.18?
error.modules.not.loaded=Jackson modules could not be loaded: {0}
7 changes: 4 additions & 3 deletions tests/integration/pom.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright (c) 2011, 2024 Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2011, 2025 Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2018 Payara Foundation and/or its affiliates. All rights reserved.

This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -80,8 +80,8 @@
<module>jersey-2846</module>
<module>jersey-2878</module>
<module>jersey-2892</module>
<module>jersey-3662</module>
<module>jersey-3796</module>
<module>jersey-3662</module>
<module>jersey-3796</module>
<module>jersey-780</module>
<module>jersey-3670</module>
<module>jersey-3992</module>
Expand All @@ -98,6 +98,7 @@
<module>portability-jersey-1</module>
<module>portability-jersey-2</module>
<module>property-check</module>
<module>resteasy-client</module>
<module>security-digest</module>
<module>servlet-2.5-autodiscovery-1</module>
<module>servlet-2.5-autodiscovery-2</module>
Expand Down
104 changes: 104 additions & 0 deletions tests/integration/resteasy-client/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright (c) 2025 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

-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.glassfish.jersey.tests.integration</groupId>
<artifactId>project</artifactId>
<version>2.47-SNAPSHOT</version>
</parent>

<artifactId>resteasy-client</artifactId>

<packaging>war</packaging>
<name>jersey-tests-integration-resteasy-client</name>

<description>
Jersey tests for Spring.Boot / Resteasy integration
</description>

<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>5.0.10.Final</version> <!-- Can use 3.5.16.Final -->
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-external</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright (c) 2025 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.springboot;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Providers;

import org.glassfish.jersey.jackson.internal.DefaultJacksonJaxbJsonProvider;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.hamcrest.Matcher;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.internal.ResteasyClientBuilderImpl;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class RestEasyClientTest extends JerseyTest {

private static final CountDownLatch readFromLatch = new CountDownLatch(1);

@Path("/")
public static class RestEasyClientTestResource {
@POST
@Path("/test")
@Produces(MediaType.APPLICATION_JSON)
public String testPost(String echo) {
return echo;
}
}

@Override
protected Application configure() {
return new ResourceConfig(RestEasyClientTestResource.class);
}

@Test
public void test() throws InterruptedException {
AtomicReference<String> messageRef = new AtomicReference<>();
Logger logger = Logger.getLogger(DefaultJacksonJaxbJsonProvider.class.getName());
logger.addHandler(new ConsoleHandler() {
@Override
public void publish(LogRecord record) {
messageRef.set(record.getMessage());
}
});
logger.setLevel(Level.FINE);

final ResteasyClient client = new ResteasyClientBuilderImpl().build();

client.register(TestDefaultJacksonJaxbJsonProvider.class);

try (final Response r = client.target(target().getUri()).path("/test")
.request().post(Entity.entity("{\"test\": \"test\"}", MediaType.APPLICATION_JSON))) {
Object o = r.readEntity(Object.class);
Assertions.assertTrue(o.toString().contains("test"));
readFromLatch.await();
Assertions.assertEquals(0, readFromLatch.getCount(), "DefaultJacksonJaxbJsonProvider has not been used");
}

client.close();
MatcherAssert.assertThat(messageRef.get(), Matchers.notNullValue());

}

public static class TestDefaultJacksonJaxbJsonProvider extends DefaultJacksonJaxbJsonProvider {
public TestDefaultJacksonJaxbJsonProvider(@Context Providers providers, @Context Configuration config) {
super(providers, config);
}

@Override
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException {
readFromLatch.countDown();
return super.readFrom(type, genericType, annotations, mediaType, httpHeaders, entityStream);
}
}

}