JAXB Reference implementation と DatatypeConverterImpl の行方

## 概要

- JAXB (Java Architecture for XML Binding) の公式に近い Reference implementation (参照実装) の jar とソースコードをバージョン毎に追いかける
- 動作確認環境: Java 11 (AdoptOpenJDK 11.0.6+10) + Gradle 6.1

## 調査した JAXB 一覧

|JAXB バージョン|パッケージ名|Gradle implementation 記述|
|-----|----------------|-----------------------------------------------|
|2.3.1|javax.xml.bind  |javax.xml.bind:jaxb-api:2.3.1                  |
|2.3.2|javax.xml.bind  |jakarta.xml.bind:jakarta.xml.bind-api:2.3.2    |
|2.3.3|javax.xml.bind  |?                                              |
|2.4.0|javax.xml.bind  |javax.xml.bind:jaxb-api:2.4.0-b180830.0359     |
|3.0.0|jakarta.xml.bind|jakarta.xml.bind:jakarta.xml.bind-api:3.0.0-RC1|

## JAXB 2.3.1

[Maven Repository: javax\.xml\.bind » jaxb\-api » 2\.3\.1](https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api/2.3.1)

build.gradle ファイルを用意。
dependencies に implementation 'javax.xml.bind:jaxb-api:2.3.1' を記述することで使用できる。

```build.gradle
plugins {
  id 'java'
  id 'application'
}

repositories {
  mavenCentral()
}

dependencies {
  implementation 'javax.xml.bind:jaxb-api:2.3.1'
}

application {
  mainClassName = 'Sample'
}
```

JAXB を使用するサンプル src/main/java/Sample.java を用意。

```java
import java.security.SecureRandom;
import javax.xml.bind.DatatypeConverter; // JAXB のクラス

public class Sample {
  public static void main(String[] args) {
    byte[] bytes = new byte[32];
    new SecureRandom().nextBytes(bytes);
    // JAXB のクラスを使用
    String str = DatatypeConverter.printHexBinary(bytes);
    System.out.println(str);
  }
}
```

gradle run で実行。

```
$ gradle run

> Task :run
20982DD2EA72EFA26763A6256209BCDC0F500C7F6BC26993FCB9690022E109FD

BUILD SUCCESSFUL in 1s
2 actionable tasks: 1 executed, 1 up-to-date
```

実行したサンプルは JAXB の内部で DatatypeConverterImpl クラスを使用している。

DatatypeConverterImpl クラスのソースコード。パッケージは javax.xml.bind となる。
GitHub 等のリポジトリでソースコードが見つからなかったため https://repo1.maven.org/maven2/javax/xml/bind/jaxb-api/2.3.1/jaxb-api-2.3.1-sources.jar を展開した。

```java
private static final char[] hexCode = "0123456789ABCDEF".toCharArray();

public String printHexBinary(byte[] data) {
    StringBuilder r = new StringBuilder(data.length * 2);
    for (byte b : data) {
        r.append(hexCode[(b >> 4) & 0xF]);
        r.append(hexCode[(b & 0xF)]);
    }
    return r.toString();
}
```

## JAXB 2.3.2 (Jakarta XML Binding 2.3.2)

Eclipse Enterprise for Java (EE4J) からの最初のリリース。
EE4J は Oracle から Java EE を移管するプロジェクト。

[2\.3\.2 \| projects\.eclipse\.org](https://projects.eclipse.org/projects/ee4j.jaxb/releases/2.3.2)

> First release from Eclipse. No API or implementation changes, just new licensing and Maven coordinates.

[2\.3\.2 \| projects\.eclipse\.org](https://projects.eclipse.org/projects/ee4j.jaxb/releases/2.3.2/plan)

> Release Date:
> Friday, December 14, 2018
> 
> Deliverables:
> Project binaries, sources and javadoc available through Maven repository.
> 
> Compatibility:
> This is the first release of Eclipse Project for JAXB, which is fully binary compatible with previous releases of the JavaTM Architecture for XML Binding API Implementation released by Oracle.

[Maven Repository: jakarta\.xml\.bind » jakarta\.xml\.bind\-api » 2\.3\.2](https://mvnrepository.com/artifact/jakarta.xml.bind/jakarta.xml.bind-api/2.3.2)

build.gradle の dependencies に以下を記述することで使用できる。

```build.gradle
dependencies {
  implementation 'jakarta.xml.bind:jakarta.xml.bind-api:2.3.2'
}
```

DatatypeConverterImpl クラスのソースコード。パッケージは javax.xml.bind となる。

https://github.com/eclipse-ee4j/jaxb-api/blob/2.3.2/jaxb-api/src/main/java/javax/xml/bind/DatatypeConverterImpl.java

```java
private static final char[] hexCode = "0123456789ABCDEF".toCharArray();

public String printHexBinary(byte[] data) {
    StringBuilder r = new StringBuilder(data.length * 2);
    for (byte b : data) {
        r.append(hexCode[(b >> 4) & 0xF]);
        r.append(hexCode[(b & 0xF)]);
    }
    return r.toString();
}
```

## JAXB 2.3.3 (Jakarta XML Binding 2.3.3)

[2\.3\.3 \| projects\.eclipse\.org](https://projects.eclipse.org/projects/ee4j.jaxb/releases/2.3.3)

> First release going through the JESP. Bug fix release of 2.3.2.
> 
> Release Date:
> Wednesday, February 19, 2020

Maven Central Repository には見つからなかった。

DatatypeConverterImpl クラスのソースコード。パッケージは javax.xml.bind となる。

https://github.com/eclipse-ee4j/jaxb-api/blob/2.3.3/jaxb-api/src/main/java/javax/xml/bind/DatatypeConverterImpl.java

```java
private static final char[] hexCode = "0123456789ABCDEF".toCharArray();

public String printHexBinary(byte[] data) {
    StringBuilder r = new StringBuilder(data.length * 2);
    for (byte b : data) {
        r.append(hexCode[(b >> 4) & 0xF]);
        r.append(hexCode[(b & 0xF)]);
    }
    return r.toString();
}
```

## JAXB 2.4.0

[Maven Repository: javax\.xml\.bind » jaxb\-api » 2\.4\.0\-b180830\.0359](https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api/2.4.0-b180830.0359)

build.gradle の dependencies に以下を記述することで使用できる。

```build.gradle
dependencies {
  implementation 'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'
}
```

DatatypeConverterImpl クラスのソースコード。パッケージは javax.xml.bind となる。
GitHub 等のリポジトリでソースコードが見つからなかったため https://repo1.maven.org/maven2/javax/xml/bind/jaxb-api/2.4.0-b180830.0359/jaxb-api-2.4.0-b180830.0359-sources.jar を展開した。

```java
private static final char[] hexCode = "0123456789ABCDEF".toCharArray();

public String printHexBinary(byte[] data) {
    StringBuilder r = new StringBuilder(data.length * 2);
    for (byte b : data) {
        r.append(hexCode[(b >> 4) & 0xF]);
        r.append(hexCode[(b & 0xF)]);
    }
    return r.toString();
}
```

似たようなバージョンのファイルが他の場所にあるが、パッケージが com.sun.xml.bind になっている別物。

[Maven Repository: com\.sun\.xml\.bind » jaxb\-ri » 2\.4\.0\-b180830\.0438](https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-ri/2.4.0-b180830.0438)

> compile group: 'com.sun.xml.bind', name: 'jaxb-ri', version: '2.4.0-b180830.0438', ext: 'pom'

https://github.com/javaee/jaxb-v2/blob/2.4.0-b180830.0438/jaxb-ri/runtime/impl/src/main/java/com/sun/xml/bind/DatatypeConverterImpl.java

```java
@Deprecated
private static final char[] hexCode = "0123456789ABCDEF".toCharArray();

@Deprecated
public String printHexBinary(byte[] data) {
    StringBuilder r = new StringBuilder(data.length * 2);
    for (byte b : data) {
        r.append(hexCode[(b >> 4) & 0xF]);
        r.append(hexCode[(b & 0xF)]);
    }
    return r.toString();
}
```

GlassFish JAXB の DatatypeConverterImpl も同じく com.sun.xml.bind パッケージだった。

[Maven Repository: org\.glassfish\.jaxb » jaxb\-runtime » 2\.4\.0\-b180830\.0438](https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime/2.4.0-b180830.0438)

## JAXB 3.0.0 (Jakarta XML Binding 3.0)

このバージョンからパッケージ名が javax.xml.bind から jakarta.xml.bind に変更されている。

[3\.0 \| projects\.eclipse\.org](https://projects.eclipse.org/projects/ee4j.jaxb/releases/3.0)

> Change javax.* package name to jakarta.*
> 
> Release Date:
> Friday, February 7, 2020
> 
> Release Type:
> Major release (API breakage)

Jakarta EE の Web サイトには 「under development (開発中)」 と書かれている。

[Jakarta XML Binding 3\.0 \(under development\) \| The Eclipse Foundation](https://jakarta.ee/specifications/xml-binding/3.0/)

[Maven Repository: jakarta\.xml\.bind » jakarta\.xml\.bind\-api » 3\.0\.0\-RC1](https://mvnrepository.com/artifact/jakarta.xml.bind/jakarta.xml.bind-api/3.0.0-RC1)

build.gradle の dependencies に以下を記述することで使用できる。

```build.gradle
dependencies {
  implementation 'jakarta.xml.bind:jakarta.xml.bind-api:3.0.0-RC1'
}
```

JAXB を使用するサンプル src/main/java/Sample.java を用意。
今回のサンプルではパッケージ名を javax.xml.bind から jakarta.xml.bind に変更しただけで動作した。

```java
import java.security.SecureRandom;
import jakarta.xml.bind.DatatypeConverter; // JAXB のクラス

public class Sample {
  public static void main(String[] args) {
    byte[] bytes = new byte[32];
    new SecureRandom().nextBytes(bytes);
    // JAXB のクラスを使用
    String str = DatatypeConverter.printHexBinary(bytes);
    System.out.println(str);
  }
}
```

DatatypeConverterImpl クラスのソースコード。パッケージは jakarta.xml.bind となる。

https://github.com/eclipse-ee4j/jaxb-api/blob/3.0.0-RC1/jaxb-api/src/main/java/jakarta/xml/bind/DatatypeConverterImpl.java

```java
private static final char[] hexCode = "0123456789ABCDEF".toCharArray();

public String printHexBinary(byte[] data) {
    StringBuilder r = new StringBuilder(data.length * 2);
    for (byte b : data) {
        r.append(hexCode[(b >> 4) & 0xF]);
        r.append(hexCode[(b & 0xF)]);
    }
    return r.toString();
}
```

## 参考資料

- [The Java Community Process\(SM\) Program \- JSRs: Java Specification Requests \- detail JSR\# 222](https://jcp.org/en/jsr/detail?id=222)
- [JAXB (https://javaee.github.io/jaxb-v2/)](https://javaee.github.io/jaxb-v2/)
    - [JAXB Release Documentation](https://javaee.github.io/jaxb-v2/doc/user-guide/)
    - [GitHub \- javaee/jaxb\-v2](https://github.com/javaee/jaxb-v2)
- [JAXB (https://eclipse-ee4j.github.io/jaxb-ri/)](https://eclipse-ee4j.github.io/jaxb-ri/)
    - [Jakarta XML Binding \| projects\.eclipse\.org](https://projects.eclipse.org/projects/ee4j.jaxb)
    - [New Maven Coordinates \- Eclipsepedia](https://wiki.eclipse.org/New_Maven_Coordinates)