Skip to content

Commit d7f572b

Browse files
committed
Extract com.xml.sun JAXB resolving to Maven module
Resolving the old javax.xml.bind JAXB 2 stuff using the ServiceLoader facilities. This enables depending projects to be able to bypass our custom stuff to load JAXB if they for some reason needs to do so (e.g. if already running in an environment using javax.xml.bind JAXB with some other implementation they want to use instead).
1 parent f378cbd commit d7f572b

File tree

12 files changed

+374
-26
lines changed

12 files changed

+374
-26
lines changed

NOTICE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ This software includes third party software subject to the following licenses:
1414
JAXB2 Basics - Runtime under BSD-Style License
1515
Old JAXB Core under CDDL+GPL License
1616
Old JAXB Runtime under Eclipse Distribution License - v 1.0
17+
Posten signering - API com.sun.xml.bind JAXB Service Loader under The Apache Software License, Version 2.0
1718
Posten signering - API JAXB Classes under The Apache Software License, Version 2.0
1819
Posten signering - API Schema under The Apache Software License, Version 2.0
1920
Posten signering - API Specification under The Apache Software License, Version 2.0
21+
SLF4J API Module under MIT License
2022

2123

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Digipost Signature API-specification
2+
3+
Copyright 2016 Posten Norge AS. All Rights Reserved.
4+
5+
This product includes software developed by Posten Norge AS. - https://www.posten.no/
6+
Licensed under Apache 2 - http://www.apache.org/licenses/LICENSE-2.0.html
7+
8+
9+
This software includes third party software subject to the following licenses:
10+
11+
Jakarta Activation under EDL 1.0
12+
JavaBeans Activation Framework API jar under CDDL/GPLv2+CE
13+
jaxb-api under CDDL 1.1 or GPL2 w/ CPE
14+
Old JAXB Core under CDDL+GPL License
15+
Old JAXB Runtime under Eclipse Distribution License - v 1.0
16+
Posten signering - API com.sun.xml.bind JAXB Service Loader under The Apache Software License, Version 2.0
17+
SLF4J API Module under MIT License
18+
19+
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<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/maven-v4_0_0.xsd">
3+
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>no.digipost.signature</groupId>
7+
<artifactId>signature-api-specification-parent</artifactId>
8+
<version>LOCAL-SNAPSHOT</version>
9+
</parent>
10+
11+
<name>Posten signering - API com.sun.xml.bind JAXB Service Loader</name>
12+
13+
<artifactId>signature-api-specification-com.sun.xml.bind-serviceloader</artifactId>
14+
15+
<properties>
16+
<project.previousVersion>set_with_-Dproject.previousVersion=X.Y</project.previousVersion>
17+
</properties>
18+
19+
<dependencyManagement>
20+
<dependencies>
21+
<dependency>
22+
<groupId>org.junit</groupId>
23+
<artifactId>junit-bom</artifactId>
24+
<version>5.9.2</version>
25+
<type>pom</type>
26+
<scope>import</scope>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.mockito</groupId>
30+
<artifactId>mockito-bom</artifactId>
31+
<version>4.11.0</version>
32+
<type>pom</type>
33+
<scope>import</scope>
34+
</dependency>
35+
</dependencies>
36+
</dependencyManagement>
37+
38+
<dependencies>
39+
<dependency>
40+
<groupId>javax.xml.bind</groupId>
41+
<artifactId>jaxb-api</artifactId>
42+
<version>2.3.1</version>
43+
</dependency>
44+
<dependency>
45+
<groupId>com.sun.xml.bind</groupId>
46+
<artifactId>jaxb-impl</artifactId>
47+
<version>2.3.8</version>
48+
<exclusions>
49+
<exclusion>
50+
<groupId>jakarta.xml.bind</groupId>
51+
<artifactId>*</artifactId>
52+
</exclusion>
53+
</exclusions>
54+
</dependency>
55+
<dependency>
56+
<groupId>com.sun.xml.bind</groupId>
57+
<artifactId>jaxb-core</artifactId>
58+
<version>2.3.0.1</version>
59+
<scope>runtime</scope>
60+
</dependency>
61+
<dependency>
62+
<groupId>org.slf4j</groupId>
63+
<artifactId>slf4j-api</artifactId>
64+
<version>1.7.36</version>
65+
</dependency>
66+
<dependency>
67+
<groupId>org.slf4j</groupId>
68+
<artifactId>slf4j-simple</artifactId>
69+
<version>1.7.36</version>
70+
<scope>test</scope>
71+
</dependency>
72+
<dependency>
73+
<groupId>org.junit.jupiter</groupId>
74+
<artifactId>junit-jupiter-api</artifactId>
75+
<scope>test</scope>
76+
</dependency>
77+
<dependency>
78+
<groupId>org.mockito</groupId>
79+
<artifactId>mockito-core</artifactId>
80+
<scope>test</scope>
81+
</dependency>
82+
</dependencies>
83+
84+
<build>
85+
<pluginManagement>
86+
<plugins>
87+
<plugin>
88+
<artifactId>maven-javadoc-plugin</artifactId>
89+
<version>3.5.0</version>
90+
<configuration>
91+
<detectOfflineLinks>false</detectOfflineLinks>
92+
<doclint>all,-missing,-html</doclint>
93+
</configuration>
94+
</plugin>
95+
<plugin>
96+
<groupId>org.jasig.maven</groupId>
97+
<artifactId>maven-notice-plugin</artifactId>
98+
<configuration>
99+
<noticeTemplate>${project.basedir}/../src/notice/NOTICE.template</noticeTemplate>
100+
</configuration>
101+
</plugin>
102+
<plugin>
103+
<groupId>com.github.siom79.japicmp</groupId>
104+
<artifactId>japicmp-maven-plugin</artifactId>
105+
<version>0.17.1</version>
106+
<configuration>
107+
<oldVersion>
108+
<dependency>
109+
<groupId>${project.groupId}</groupId>
110+
<artifactId>${project.artifactId}</artifactId>
111+
<version>${project.previousVersion}</version>
112+
</dependency>
113+
</oldVersion>
114+
<newVersion>
115+
<file>
116+
<path>${project.build.directory}/${project.build.finalName}.${project.packaging}</path>
117+
</file>
118+
</newVersion>
119+
<parameter>
120+
<onlyModified>true</onlyModified>
121+
<onlyBinaryIncompatible>true</onlyBinaryIncompatible>
122+
<includes>
123+
<include>no.digipost</include>
124+
</includes>
125+
</parameter>
126+
</configuration>
127+
</plugin>
128+
</plugins>
129+
</pluginManagement>
130+
<plugins>
131+
<plugin>
132+
<artifactId>maven-dependency-plugin</artifactId>
133+
<executions>
134+
<execution>
135+
<goals>
136+
<goal>analyze-only</goal>
137+
</goals>
138+
<configuration>
139+
<failOnWarning>true</failOnWarning>
140+
<ignoreNonCompile>true</ignoreNonCompile>
141+
</configuration>
142+
</execution>
143+
</executions>
144+
</plugin>
145+
</plugins>
146+
</build>
147+
148+
</project>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (C) Posten Norge AS
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package no.digipost.jaxb;
17+
18+
import org.slf4j.Logger;
19+
import org.slf4j.LoggerFactory;
20+
21+
import javax.xml.bind.JAXBContext;
22+
import javax.xml.bind.JAXBContextFactory;
23+
import javax.xml.bind.JAXBException;
24+
25+
import java.util.Map;
26+
import java.util.stream.Stream;
27+
28+
import static java.util.stream.Collectors.joining;
29+
30+
class ComSunXmlBindJAXBContextFactory implements JAXBContextFactory {
31+
32+
private static final Logger LOG = LoggerFactory.getLogger(ComSunXmlBindJAXBContextFactory.class);
33+
private final JAXBContextFactory delegate = new com.sun.xml.bind.v2.JAXBContextFactory();
34+
35+
@Override
36+
public JAXBContext createContext(Class<?>[] classesToBeBound, Map<String, ?> properties) throws JAXBException {
37+
JAXBContext jaxbContext = delegate.createContext(classesToBeBound, properties);
38+
LOG.info("Creating new JAXB context of type {} for classes {}", jaxbContext.getClass().getName(), Stream.of(classesToBeBound).map(Class::getSimpleName).collect(joining(", ", "[", "]")));
39+
return jaxbContext;
40+
}
41+
42+
@Override
43+
public JAXBContext createContext(String contextPath, ClassLoader classLoader, Map<String, ?> properties) throws JAXBException {
44+
JAXBContext jaxbContext = delegate.createContext(contextPath, classLoader, properties);
45+
LOG.info("Creating new JAXB context of type {} for contextPath {}", jaxbContext.getClass().getName(), contextPath);
46+
return jaxbContext;
47+
}
48+
49+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (C) Posten Norge AS
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package no.digipost.jaxb;
17+
18+
import javax.xml.bind.JAXBContext;
19+
import javax.xml.bind.JAXBContextFactory;
20+
import javax.xml.bind.JAXBException;
21+
22+
import java.util.Map;
23+
24+
public class StaticJAXBContextFactory {
25+
26+
static JAXBContextFactory factory = new ComSunXmlBindJAXBContextFactory();
27+
28+
public static JAXBContext createContext(Class<?>[] classesToBeBound, Map<String, ?> properties) throws JAXBException {
29+
return factory.createContext(classesToBeBound, properties);
30+
}
31+
32+
public static JAXBContext createContext(String contextPath, ClassLoader classLoader, Map<String, ?> properties) throws JAXBException {
33+
return factory.createContext(contextPath, classLoader, properties);
34+
}
35+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
no.digipost.jaxb.StaticJAXBContextFactory
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (C) Posten Norge AS
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package no.digipost.jaxb;
17+
18+
import org.junit.jupiter.api.Test;
19+
20+
import javax.xml.bind.JAXBContext;
21+
import javax.xml.bind.JAXBContextFactory;
22+
import javax.xml.bind.JAXBException;
23+
24+
import java.util.Optional;
25+
import java.util.concurrent.atomic.AtomicInteger;
26+
27+
import static org.junit.jupiter.api.Assertions.assertEquals;
28+
import static org.mockito.ArgumentMatchers.any;
29+
import static org.mockito.ArgumentMatchers.same;
30+
import static org.mockito.Mockito.spy;
31+
import static org.mockito.Mockito.verify;
32+
33+
class JaxbContextFactoryResolveTest {
34+
35+
private static final Class<?>[] jaxbClasses = { MyJaxbEntity.class };
36+
37+
@Test
38+
void resolvesStaticJAXBContextFactory() throws JAXBException {
39+
JAXBContextFactory realFactory = StaticJAXBContextFactory.factory;
40+
JAXBContextFactory spiedFactory = spy(realFactory);
41+
try {
42+
StaticJAXBContextFactory.factory = spiedFactory;
43+
JAXBContext.newInstance(jaxbClasses);
44+
} finally {
45+
StaticJAXBContextFactory.factory = realFactory;
46+
}
47+
verify(spiedFactory).createContext(same(jaxbClasses), any());
48+
}
49+
50+
@Test
51+
void overrideStaticJAXBContextFactoryUsingSystemProperty() throws JAXBException {
52+
Optional<String> existingFactoryPropertyValue = Optional.ofNullable(System.getProperty(JAXBContext.JAXB_CONTEXT_FACTORY));
53+
AtomicInteger invocationCounter = OverriddenJAXBContextFactory.countInteractionsIn(new AtomicInteger());
54+
try {
55+
System.setProperty(JAXBContext.JAXB_CONTEXT_FACTORY, "no.digipost.jaxb.OverriddenJAXBContextFactory");
56+
JAXBContext.newInstance(jaxbClasses);
57+
} finally {
58+
existingFactoryPropertyValue
59+
.map(value -> System.setProperty(JAXBContext.JAXB_CONTEXT_FACTORY, value))
60+
.orElseGet(() -> System.clearProperty(JAXBContext.JAXB_CONTEXT_FACTORY));
61+
}
62+
assertEquals(1, invocationCounter.get(), "invocations on overridden JAXBContext factory");
63+
}
64+
65+
66+
static class MyJaxbEntity {
67+
68+
}
69+
70+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (C) Posten Norge AS
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package no.digipost.jaxb;
17+
18+
import javax.xml.bind.JAXBContext;
19+
import javax.xml.bind.JAXBException;
20+
21+
import java.util.Collection;
22+
import java.util.Map;
23+
import java.util.concurrent.ConcurrentLinkedDeque;
24+
import java.util.concurrent.atomic.AtomicInteger;
25+
26+
public class OverriddenJAXBContextFactory {
27+
28+
private static final Collection<AtomicInteger> invocationCounters = new ConcurrentLinkedDeque<>();
29+
30+
public static JAXBContext createContext(Class<?>[] classesToBeBound, Map<String, ?> properties) throws JAXBException {
31+
invocationCounters.forEach(AtomicInteger::incrementAndGet);
32+
return StaticJAXBContextFactory.createContext(classesToBeBound, properties);
33+
}
34+
35+
public static AtomicInteger countInteractionsIn(AtomicInteger count) {
36+
invocationCounters.add(count);
37+
return count;
38+
}
39+
}

jaxb/NOTICE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ This software includes third party software subject to the following licenses:
1414
JAXB2 Basics - Runtime under BSD-Style License
1515
Old JAXB Core under CDDL+GPL License
1616
Old JAXB Runtime under Eclipse Distribution License - v 1.0
17+
Posten signering - API com.sun.xml.bind JAXB Service Loader under The Apache Software License, Version 2.0
1718
Posten signering - API JAXB Classes under The Apache Software License, Version 2.0
19+
SLF4J API Module under MIT License
1820

1921

0 commit comments

Comments
 (0)