개발 중 Protobuf 3.6.1을 사용하여 템플릿 코드를 생성했는데, HBase 1.2.1-cdh5.1.4.0과 함께 사용할 때 버전 충돌이 발생했습니다. Maven 의존성 트리를 확인하면 HBase가 Protobuf 2.5.0을 내장하고 있음을 알 수 있습니다.
빌드 단계에서는 문제가 없지만, 런타임 시 다음 오류가 발생합니다:
java.lang.ClassNotFoundException: com.google.protobuf.LiteralByteString
이 문제를 해결하기 위해 먼저 Maven에서 HBase의 Protobuf 의존성을 제외하는 방법을 시도했습니다:
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>${hbase.version}-${cdh.version}</version>
<exclusions>
<exclusion>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-protocol</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-server</artifactId>
<version>${hbase.version}-${cdh.version}</version>
<exclusions>
<exclusion>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-protocol</artifactId>
</exclusion>
</exclusions>
</dependency>
하지만 실제 운영 환경에서 실행했을 때, 애플리케이션이 멈추는 현상이 발생했습니다. 이는 단순히 저버전 의존성을 제거하는 것으로는 해결되지 않았습니다.
가장 효과적인 해결 방법은 Protobuf 3.x의 패키지 구조를 변경하여, HBase의 Protobuf 2.5.0과 충돌하지 않도록 하는 것입니다. HBase는 shaded 버전을 제공하여 내부 패키지명을 변경할 수 있습니다:
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-shaded-client</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-shaded-server</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.htrace</groupId>
<artifactId>htrace-core</artifactId>
<version>3.1.0-incubating</version>
</dependency>
동시에 Protobuf 3.6.1 의존성은 그대로 유지합니다:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.6.1</version>
</dependency>
이렇게 하면 Protobuf 3.x로 작성된 직렬화 코드는 정상 작동하고, HBase는 자체적으로 변경된 패키지명을 사용하여 충돌 없이 통신할 수 있습니다. 위 설정으로 빌드 및 실행 시 문제가 해결되었습니다.