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
23 changes: 13 additions & 10 deletions api/src/main/java/jakarta/xml/bind/ContextFinder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand Down Expand Up @@ -310,7 +310,7 @@ static JAXBContext find(String factoryId,
}
}
if (factoryName != null) {
return newInstance(contextPath, contextPathClasses, factoryName, classLoader, properties);
return newInstance(contextPath, contextPathClasses, factoryName, classLoader, cleanProperties(properties));
}
}

Expand Down Expand Up @@ -354,14 +354,7 @@ static JAXBContext find(Class<?>[] classes, Map<String, ?> properties) throws JA
}
}
if (factoryClassName != null) {
//Providers are not required to understand JAXB_CONTEXT_FACTORY property
//and they must throw a JAXBException if they see it, so we need to remove it
//from properties passed to them
Map<String, ?> props = properties.entrySet()
.stream()
.filter(Predicate.not(e -> JAXBContext.JAXB_CONTEXT_FACTORY.equals(e.getKey())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return newInstance(classes, props, factoryClassName);
return newInstance(classes, cleanProperties(properties), factoryClassName);
}
}

Expand Down Expand Up @@ -396,6 +389,16 @@ private static String classNameFromSystemProperties() throws JAXBException {
return null;
}

private static Map<String, ?> cleanProperties(Map<String, ?> properties) {
// Providers are not required to understand JAXB_CONTEXT_FACTORY property,
// and they must throw a JAXBException if they see it, so we need to remove it
// from properties passed to them
return properties.entrySet()
.stream()
.filter(Predicate.not(e -> JAXBContext.JAXB_CONTEXT_FACTORY.equals(e.getKey())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

private static String getSystemProperty(String property) {
logger.log(Level.FINE, "Checking system property {0}", property);
String value = AccessController.doPrivileged(new GetPropertyAction(property));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand All @@ -25,6 +25,7 @@
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.logging.Logger;

import static junit.framework.TestCase.assertTrue;
Expand Down Expand Up @@ -73,6 +74,9 @@ public class JAXBContextTest {
// scenario name - just for logging
String scenario;

// properties to pass to JAXBContext#newContext
private Map<String, ?> properties;

// java policy file for testing w/security manager
private String expectedFactory;
private Class<?> expectedException;
Expand All @@ -83,70 +87,74 @@ public static Collection configurations() {
return Arrays.asList(new Object[][]{
// scenario-name, jaxb.properties, svc, arg1, arg2, system-props
// {"scenario-1", FACTORY_ID_LEGACY + "="+PACKAGE_LEGACY+"Valid", null, PACKAGE_LEGACY+"Valid$JAXBContext1", null, null},
{"scenario-3", FACTORY_ID_LEGACY + "=non.existing.FactoryClass", null, null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-4", FACTORY_ID_LEGACY + "="+PACKAGE_LEGACY+"Invalid", null, null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-3", FACTORY_ID_LEGACY + "=non.existing.FactoryClass", null, null, jakarta.xml.bind.JAXBException.class, null, null},
{"scenario-4", FACTORY_ID_LEGACY + "="+PACKAGE_LEGACY+"Invalid", null, null, jakarta.xml.bind.JAXBException.class, null, null},
// {"scenario-13", FACTORY_ID_LEGACY + "="+PACKAGE_LEGACY+"Valid", PACKAGE_LEGACY+"Valid2", PACKAGE_LEGACY+"Valid$JAXBContext1", null, PACKAGE_LEGACY+"Valid3"},

// {"scenario-1", FACTORY_ID_LEGACY + "="+PACKAGE_SPI+"Valid", null, PACKAGE_SPI+"Valid$JAXBContext1", null, null},
{"scenario-3", FACTORY_ID_LEGACY + "=non.existing.FactoryClass", null, null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-4", FACTORY_ID_LEGACY + "="+PACKAGE_SPI+"Invalid", null, null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-3", FACTORY_ID_LEGACY + "=non.existing.FactoryClass", null, null, jakarta.xml.bind.JAXBException.class, null, null},
{"scenario-4", FACTORY_ID_LEGACY + "="+PACKAGE_SPI+"Invalid", null, null, jakarta.xml.bind.JAXBException.class, null, null},
// {"scenario-13", FACTORY_ID_LEGACY + "="+PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid2", PACKAGE_SPI+"Valid$JAXBContext1", null, PACKAGE_SPI+"Valid3"},

// {"scenario-1", FACTORY_ID + "="+PACKAGE_SPI+"Valid", null, PACKAGE_SPI+"Valid$JAXBContext1", null, null},
{"scenario-3", FACTORY_ID + "=non.existing.FactoryClass", null, null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-4", FACTORY_ID + "="+PACKAGE_SPI+"Invalid", null, null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-3", FACTORY_ID + "=non.existing.FactoryClass", null, null, jakarta.xml.bind.JAXBException.class, null, null},
{"scenario-4", FACTORY_ID + "="+PACKAGE_SPI+"Invalid", null, null, jakarta.xml.bind.JAXBException.class, null, null},
// {"scenario-13", FACTORY_ID + "="+PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid2", PACKAGE_SPI+"Valid$JAXBContext1", null, PACKAGE_SPI+"Valid3"},

// {"scenario-1", FACTORY_ID + "="+PACKAGE_LEGACY+"Valid", null, PACKAGE_LEGACY+"Valid$JAXBContext1", null, null},
{"scenario-3", FACTORY_ID + "=non.existing.FactoryClass", null, null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-4", FACTORY_ID + "="+PACKAGE_LEGACY+"Invalid", null, null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-3", FACTORY_ID + "=non.existing.FactoryClass", null, null, jakarta.xml.bind.JAXBException.class, null, null},
{"scenario-4", FACTORY_ID + "="+PACKAGE_LEGACY+"Invalid", null, null, jakarta.xml.bind.JAXBException.class, null, null},
// {"scenario-13", FACTORY_ID + "="+PACKAGE_LEGACY+"Valid", PACKAGE_LEGACY+"Valid2", PACKAGE_LEGACY+"Valid$JAXBContext1", null, PACKAGE_LEGACY+"Valid3"},


{"scenario-2", "something=AnotherThing", null, null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-2", "something=AnotherThing", null, null, jakarta.xml.bind.JAXBException.class, null, null},

// service loader
{"scenario-8", null, PACKAGE_SPI+"Valid\n", PACKAGE_SPI+"Valid$JAXBContext1", null, null},
{"scenario-9", null, PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid$JAXBContext1", null, null},
{"scenario-11", null, PACKAGE_SPI+"Invalid", null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-15", null, PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid$JAXBContext1", null, null},
{"scenario-8", null, PACKAGE_SPI+"Valid\n", PACKAGE_SPI+"Valid$JAXBContext1", null, null, null},
{"scenario-9", null, PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid$JAXBContext1", null, null, null},
{"scenario-11", null, PACKAGE_SPI+"Invalid", null, jakarta.xml.bind.JAXBException.class, null, null},
{"scenario-15", null, PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid$JAXBContext1", null, null, null},

// service loader - legacy
// {"scenario-8 legacy-svc", null, PACKAGE_SPI+"Valid\n", PACKAGE_SPI+"Valid$JAXBContext1", null, null},
// {"scenario-9 legacy-svc", null, PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid$JAXBContext1", null, null},
{"scenario-11 legacy-svc", null, PACKAGE_SPI+"Invalid", null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-11 legacy-svc", null, PACKAGE_SPI+"Invalid", null, jakarta.xml.bind.JAXBException.class, null, null},
// {"scenario-15 legacy-svc", null, PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid$JAXBContext1", null, null},

// service loader - legacy
// {"scenario-8 legacy-svc", null, PACKAGE_LEGACY+"Valid\n", PACKAGE_LEGACY+"Valid$JAXBContext1", null, null},
// {"scenario-9 legacy-svc", null, PACKAGE_LEGACY+"Valid", PACKAGE_LEGACY+"Valid$JAXBContext1", null, null},
{"scenario-11 legacy-svc", null, PACKAGE_LEGACY+"Invalid", null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-11 legacy-svc", null, PACKAGE_LEGACY+"Invalid", null, jakarta.xml.bind.JAXBException.class, null, null},
// {"scenario-15 legacy-svc", null, PACKAGE_LEGACY+"Valid", PACKAGE_LEGACY+"Valid$JAXBContext1", null, null},

// system property
{"scenario-5", null, null, PACKAGE_SPI+"Valid$JAXBContext1", null, PACKAGE_SPI+"Valid"},
{"scenario-7", null, null, null, jakarta.xml.bind.JAXBException.class, PACKAGE_SPI+"Invalid"},
{"scenario-14", null, PACKAGE_SPI+"Valid2", PACKAGE_SPI+"Valid$JAXBContext1", null, PACKAGE_SPI+"Valid"},
{"scenario-5", null, null, PACKAGE_SPI+"Valid$JAXBContext1", null, PACKAGE_SPI+"Valid", null},
{"scenario-7", null, null, null, jakarta.xml.bind.JAXBException.class, PACKAGE_SPI+"Invalid", null},
{"scenario-14", null, PACKAGE_SPI+"Valid2", PACKAGE_SPI+"Valid$JAXBContext1", null, PACKAGE_SPI+"Valid", null},

{"scenario-5", null, null, PACKAGE_LEGACY+"Valid$JAXBContext1", null, PACKAGE_LEGACY+"Valid", null},
{"scenario-7", null, null, null, jakarta.xml.bind.JAXBException.class, PACKAGE_LEGACY+"Invalid", null},
{"scenario-14", null, PACKAGE_LEGACY+"Valid2", PACKAGE_LEGACY+"Valid$JAXBContext1", null, PACKAGE_LEGACY+"Valid", null},
{"scenario-6", null, null, null, jakarta.xml.bind.JAXBException.class, "jaxb.factory.NonExisting", null},

{"scenario-5", null, null, PACKAGE_LEGACY+"Valid$JAXBContext1", null, PACKAGE_LEGACY+"Valid"},
{"scenario-7", null, null, null, jakarta.xml.bind.JAXBException.class, PACKAGE_LEGACY+"Invalid"},
{"scenario-14", null, PACKAGE_LEGACY+"Valid2", PACKAGE_LEGACY+"Valid$JAXBContext1", null, PACKAGE_LEGACY+"Valid"},
{"scenario-6", null, null, null, jakarta.xml.bind.JAXBException.class, "jaxb.factory.NonExisting"},
{"scenario-10", null, "jaxb.factory.NonExisting", null, jakarta.xml.bind.JAXBException.class, null, null},

{"scenario-10", null, "jaxb.factory.NonExisting", null, jakarta.xml.bind.JAXBException.class, null},
{"scenario-12", null, null, DEFAULT, jakarta.xml.bind.JAXBException.class, null, null},

{"scenario-12", null, null, DEFAULT, jakarta.xml.bind.JAXBException.class, null},
// properties
{"scenario-17", null, PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid$JAXBContext1", null, null, Map.of("jakarta.xml.bind.JAXBContextFactory", PACKAGE_SPI+"Valid")},
});
}

// scenario-name, jaxb.properties, svc, arg1, arg2, system-props
// scenario-name, jaxb.properties, svc, arg1, arg2, system-props, properties
public JAXBContextTest(
String scenario,
String jaxbPropertiesClass,
String spiClass,
String expectedFactory,
Class<?> expectedException,
String systemProperty
String systemProperty,
Map<String, ?> properties
) {

// ensure setup may be done ...
Expand All @@ -161,6 +169,7 @@ public JAXBContextTest(
this.scenario = scenario;
this.expectedFactory = expectedFactory;
this.expectedException = expectedException;
this.properties = properties;

if (skipUnsafe && scenario.startsWith("unsafe")) {
log("Skipping unsafe scenario:" + scenario);
Expand All @@ -187,7 +196,20 @@ public void testPath() throws IOException {
public void testClasses() throws IOException {
logConfigurations();
try {
JAXBContext ctx = JAXBContext.newInstance(new Class[] {A.class}, null);
JAXBContext ctx = JAXBContext.newInstance(new Class<?>[] {A.class}, properties);
handleResult(ctx);
} catch (Throwable throwable) {
handleThrowable(throwable);
} finally {
doFinally();
}
}

@Test
public void testClassLoader() throws IOException {
logConfigurations();
try {
JAXBContext ctx = JAXBContext.newInstance(A.class.getName(), JAXBContextTest.class.getClassLoader(), properties);
handleResult(ctx);
} catch (Throwable throwable) {
handleThrowable(throwable);
Expand Down
8 changes: 7 additions & 1 deletion jaxb-api-test/src/test/java/jaxb/factory/spi/Valid.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand All @@ -24,11 +24,17 @@ public class Valid implements JAXBContextFactory {

@Override
public JAXBContext createContext(Class<?>[] classesToBeBound, Map<String, ?> properties) throws JAXBException {
if (properties != null && properties.containsKey("jakarta.xml.bind.JAXBContextFactory")) {
throw new JAXBException("property \"jakarta.xml.bind.JAXBContextFactory\" is not supported");
}
return new JAXBContext1();
}

@Override
public JAXBContext createContext(String contextPath, ClassLoader classLoader, Map<String, ?> properties) throws JAXBException {
if (properties != null && properties.containsKey("jakarta.xml.bind.JAXBContextFactory")) {
throw new JAXBException("property \"jakarta.xml.bind.JAXBContextFactory\" is not supported");
}
return new JAXBContext1();
}

Expand Down
8 changes: 7 additions & 1 deletion jaxb-api-test/src/test/java/jaxb/factory/spi/Valid2.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand All @@ -24,11 +24,17 @@ public class Valid2 implements JAXBContextFactory {

@Override
public JAXBContext createContext(Class<?>[] classesToBeBound, Map<String, ?> properties) throws JAXBException {
if (properties != null && properties.containsKey("jakarta.xml.bind.JAXBContextFactory")) {
throw new JAXBException("property \"jakarta.xml.bind.JAXBContextFactory\" is not supported");
}
return new JAXBContext1();
}

@Override
public JAXBContext createContext(String contextPath, ClassLoader classLoader, Map<String, ?> properties) throws JAXBException {
if (properties != null && properties.containsKey("jakarta.xml.bind.JAXBContextFactory")) {
throw new JAXBException("property \"jakarta.xml.bind.JAXBContextFactory\" is not supported");
}
return new JAXBContext1();
}

Expand Down
8 changes: 7 additions & 1 deletion jaxb-api-test/src/test/java/jaxb/factory/spi/Valid3.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand All @@ -24,11 +24,17 @@ public class Valid3 implements JAXBContextFactory {

@Override
public JAXBContext createContext(Class<?>[] classesToBeBound, Map<String, ?> properties) throws JAXBException {
if (properties != null && properties.containsKey("jakarta.xml.bind.JAXBContextFactory")) {
throw new JAXBException("property \"jakarta.xml.bind.JAXBContextFactory\" is not supported");
}
return new JAXBContext1();
}

@Override
public JAXBContext createContext(String contextPath, ClassLoader classLoader, Map<String, ?> properties) throws JAXBException {
if (properties != null && properties.containsKey("jakarta.xml.bind.JAXBContextFactory")) {
throw new JAXBException("property \"jakarta.xml.bind.JAXBContextFactory\" is not supported");
}
return new JAXBContext1();
}

Expand Down