본문 바로가기

JAVA

XSD 를 Java 소스로 변환하기 - 메이븐 프로젝트 활용

나의 경우 외부에서 제공하는 웹서비스를 사용하는 프로젝트를 하게 되면 보통 매우 복잡한 수많은 XSD 문서를 전달받게 되는데 내용이 방대하다 보니 웹서비스를 호출 결과를 직접 파싱하여 객체에 담는 대신 전달 받은 XSD 를 Java 소스로 변환 하여 웹서비스 응답이 생성된 객체로 매핑되도록 한다. 아마도 이렇게 작업하는 사람이 많지 않을까 한다. 

 

기존까지는 커맨드 창에서 xjc 명령어를 이용해 xsd 를 java 소스로 만들었는데 .. 이렇게 하다보니 한가지 불편한 부분이 있었으나 개션하지 않고 있었던 부분이 있었다. 소스코드파일이 주석으로 인해 굉장히 커지는 문제다. 생성된 Java 소스를 확인해 보면 각 클래스마다 주석으로 그 클래스에 대한 스키마 구조가 그대로 붙여 있는데 XSD 가 큰경우 이 양이 매우 많아진다. 쓸데없는 주석의 양만 만라인 정도가 생기는 수준이다. 나는 개발툴로 이클립스를 사용하고 있는데 이렇게 사이즈가 큰 파일이 많아지다 보니 툴이 느려지는 현상이 발생하는 것이다. 이를 해소하기 위해 xjc 에서 java 소스 생성시 주석은 제외하는 옵션은 없는지 확인했으나 커맨드 창에서 호출하는 방식으로는 그 방법을 찾지 못했으며, 사이트를 헤매며 여러 예제를 찾아보면서 메이븐 프로젝트의 jaxb2-maven-plugin 은 이용하면 이 문제를 해결할 수 있을 줄 알았다...

 

그러나.. 내가 사용하는 jdk 버전으로 인해 jaxb2-maven-plugin 을 사용할 수 없는 문제를 겪었다.  나는 openjdk12 버전을 사용하고 있는데, jdk11 버전 부터 JaxB 구현이 jdk 에 기본적으로 포함되지 않는데(https://dzone.com/articles/running-jaxb-xjc-compiler-with-openjdk-11) 스키마를 Java 소스로 만드는데 사용되는 xjc 컴파일러가 이를 사용하기 때문이다. 그래서 jdk1.8 을 설치하고 설정을 진행하려고 준비하는 동안 누군가 이 문제를 해결한 플러그인을 깃헙에 올려 놓았다. 위치는 아래와 같다. 

https://github.com/davidmoten/jax-maven-plugin

 

davidmoten/jax-maven-plugin

maven plugin support for xjc, wsimport, wsgen, schemagen for Java 8,9,10,11+ - davidmoten/jax-maven-plugin

github.com

jax-maven-plugin 이며, openjdk12 에서 사용시 자바 소스가 정상적으로 사용되는 것을 확인할 수 있었다. 

 

내가 적용해본 샘플을 다음과 같이 공유 한다. 

 

아래와 같은 구조로 비어있는 메이븐 프로젝트를 만들고 

 

테스트 프로젝트 구조

 

pom.xml 을 다음과 같이 설정한다. 

<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>
	<!-- https://github.com/davidmoten/jax-maven-plugin 참조 -->

	<parent>
		<groupId>com.github.davidmoten</groupId>
		<artifactId>jax-maven-plugin-parent</artifactId>
		<version>0.1.8</version>
	</parent>

	<groupId>com.ybtour</groupId>
	<artifactId>xsd-to-java-generator</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>xsd-to-java-generator</name>
	<url>http://maven.apache.org</url>

	<properties>
		<jaxb.generated>${project.build.directory}/generated-sources/jaxb</jaxb.generated>
		<jaxws.generated.sources>${project.build.directory}/generated-sources/jaxws</jaxws.generated.sources>
		<jaxws.generated.classes>${project.build.directory}/generated-classes/jaxws</jaxws.generated.classes>
		<jaxws.generated.resources>${project.build.directory}/generated-resources/jaxws</jaxws.generated.resources>
		<javadoc.version>3.0.1</javadoc.version>
		<jaxb2.basics.version>1.11.1</jaxb2.basics.version>
	</properties>

	<dependencies>
		<!-- Java 11 needs these so the generated classes will compile -->
		<!-- Java 8, 9, 10 don't seem to be bothered by the existence of these 
			deps -->

		<dependency>
			<groupId>${project.parent.groupId}</groupId>
			<artifactId>jax-maven-plugin-test-jaxb</artifactId>
			<version>${project.parent.version}</version>
		</dependency>

		<!-- required to support plugin execution `from-dtd-usePlugins` -->
		<dependency>
			<groupId>org.jvnet.jaxb2_commons</groupId>
			<artifactId>jaxb2-basics</artifactId>
			<version>${jaxb2.basics.version}</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>${compiler.plugin.version}</version>
				<configuration>
					<source>${maven.compiler.target}</source>
					<target>${maven.compiler.target}</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>com.github.davidmoten</groupId>
				<artifactId>jax-maven-plugin</artifactId>
				<version>${project.parent.version}</version>
				<dependencies>
					<dependency>
						<groupId>org.jvnet.jaxb2_commons</groupId>
						<artifactId>jaxb2-basics</artifactId>
						<version>${jaxb2.basics.version}</version>
					</dependency>
				</dependencies>
				<executions>
					<execution>
						<id>gen-from-xsd-</id>
						<phase>generate-sources</phase>
						<goals>
							<goal>xjc</goal>
						</goals>
						<configuration>
							<systemProperties>
								<enableExternalEntityProcessing>true</enableExternalEntityProcessing>
							</systemProperties>
							<arguments>
								<!-- These are the arguments you would normally have put with a call 
									to xjc -->
								<!-- <argument>-verbose</argument> -->
								<!-- xjc -d src -p com.projectname.place.functionality xmlSchema.xsd -->
								<!-- 커맨드 창에서 xjc 명령어 사용하듯 설정하면 된다. -->
								<argument>-d</argument>
								<argument>${jaxb.generated}-dontinclude</argument>
								<argument>-p</argument>
								<argument>com.ybtour.</argument>
								<argument>${project.basedir}/src/main/jaxb/xsd</argument>
								<argument>-b</argument>
								<argument>${project.basedir}/src/main/jaxb/bindings</argument>
							</arguments>
						</configuration>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<groupId>com.google.code.maven-replacer-plugin</groupId>
				<artifactId>maven-replacer-plugin</artifactId>
				<executions>
					<execution>
						<phase>prepare-package</phase>
						<goals>
							<goal>replace</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<!-- 생성되는 자바 소스파일 위치 -->
					<includes>
						<include>target/generated-sources/jaxb-dontinclude/**/*.java</include>
					</includes>
					<regex>true</regex>
					<regexFlags>
						<regexFlag>MULTILINE</regexFlag>
					</regexFlags>
					<!-- 생성되는 자바 소스파일의 모든 주석을 제거한다. -->
					<replacements>
						<replacement>
							<token>([^:]//[^\n]*)</token>
							<value></value>
						</replacement>
						<replacement>
							<token>(?s)/\*.*?\*/</token>
							<value></value>
						</replacement>
					</replacements>
				</configuration>
			</plugin>
			<plugin>
				<groupId>net.revelc.code.formatter</groupId>
				<artifactId>formatter-maven-plugin</artifactId>
				<version>2.11.0</version>
				<executions>
					<execution>
						<phase>prepare-package</phase>
						<goals>
							<goal>format</goal>
						</goals>
						<configuration>
							<configFile>src/main/resources/eclipse/formatter.xml</configFile>
							<!-- 포매팅 시킬 소스의 위치  -->
							<directories>
								<directory>target/generated-sources/jaxb-dontinclude/com/ybtour</directory>
							</directories>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>

		<!-- FOR ECLIPSE ONLY, DISABLES A WARNING -->
		<!-- 다음 설정이 없을 경우 이클립스 기준 아래와 같은 오류 발생 Plugin execution not covered by 
			lifecycle configuration: com.github.davidmoten:jax-maven-plugin:0.1.8:xjc 
			(execution: gen-from-xsd-kml-episode-gen, phase: generate-sources) pom.xml 
			/xsd-to-java-generator line 70 Maven Project Build Lifecycle Mapping Problem -->
		<pluginManagement>
			<plugins>
				<!--This plugin's configuration is used to store Eclipse m2e settings 
					only. It has no influence on the Maven build itself. -->
				<plugin>
					<groupId>org.eclipse.m2e</groupId>
					<artifactId>lifecycle-mapping</artifactId>
					<version>1.0.0</version>
					<configuration>
						<lifecycleMappingMetadata>
							<pluginExecutions>
								<pluginExecution>
									<pluginExecutionFilter>
										<groupId>
											com.github.davidmoten
										</groupId>
										<artifactId>
											jax-maven-plugin
										</artifactId>
										<versionRange>
											[0.1.4-SNAPSHOT,)
										</versionRange>
										<goals>
											<goal>wsimport</goal>
											<goal>wsgen</goal>
											<goal>xjc</goal>
											<goal>schemagen</goal>
										</goals>
									</pluginExecutionFilter>
									<action>
										<ignore />
									</action>
								</pluginExecution>
							</pluginExecutions>
						</lifecycleMappingMetadata>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
</project>

pom.xml 설정 후, 아래그림과 같이 "Maven generate-sources" 를 실행하면 생성된 소스를 확인할 수 있다. 

 

 

메이븐을 이용해 소스를 생성한다.

참고로, 내가 테스트로 생성한 자바 파일 중 가장 큰 파일을 기준으로,

 

주석을 제거 하지 않았을 때 파일 사이즈  188,248  bytes

불필요한 주석을 제거 했을 때 48,647  bytes

주석 제거 후, 포매팅 했을 때 37,516  bytes

'JAVA' 카테고리의 다른 글

Java 제네릭 기본  (0) 2020.04.26
자바 함수형 프로그래밍 기술 7가지  (0) 2020.04.03
Apache Pulsar 정리 (kafka와 비교)  (0) 2019.12.15
Calendar 예제  (0) 2011.05.28
JSON 테스트  (0) 2011.05.28