前言
Mvn编译打包见Maven命令行编译Git源码 & flume-ng-sql-source源码编译打包
问题
使用CDH中的flume监听sql数据时,需要打一个 flume-ng-sql-souce.jar 的插件,将其编译打包后,运行flume任务会出现如下的报错:
java.lang.NoSuchMethodError:
org.apache.flume.Context.getSubProperties(Ljava/lang/String;)Lcom/google/common/collect/ImmutableMap;
19/12/26 18:42:43 ERROR node.PollingPropertiesFileConfigurationProvider: Unhandled error
java.lang.NoSuchMethodError: org.apache.flume.Context.getSubProperties(Ljava/lang/String;)Lcom/google/common/collect/ImmutableMap;
at org.keedio.flume.source.HibernateHelper.<init>(HibernateHelper.java:49)
at org.keedio.flume.source.SQLSource.configure(SQLSource.java:85)
at org.apache.flume.conf.Configurables.configure(Configurables.java:41)
at org.apache.flume.node.AbstractConfigurationProvider.loadSources(AbstractConfigurationProvider.java:325)
at org.apache.flume.node.AbstractConfigurationProvider.getConfiguration(AbstractConfigurationProvider.java:105)
at org.apache.flume.node.PollingPropertiesFileConfigurationProvider$FileWatcherRunnable.run(PollingPropertiesFileConfigurationProvider.java:145)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
^C19/12/26 18:47:46 INFO lifecycle.LifecycleSupervisor: Stopping lifecycle supervisor 11
原因
GitHub上给出的解释是:
in flume-1.8.0-cdh6.0.1, org.apache.flume.Context.getSubProperties return java.util.Map, not com.google.common.collect.ImmutableMap.
即CDH中Flume返回类型getSubProperties不匹配:
org.apache.flume.context类在方法flume-ng-configuration-1.9.0-cdh6.2.0.jar、flume-ng-configuration.jar包里面
查看这个两个jar包,里面都是有方法:public Map<String, String> getSubProperties(String prefix)
放进去的flume-ng-sql-source-1.5.2.jar也有这个方法,但是返回值类型不一样,本身的Jar包里面返回值类型是Map,而新增的这个包里面的方法返回值类型是ImmutableMap
public Map<String, String> getSubProperties(String prefix) {
Preconditions.checkArgument(prefix.endsWith("."),
"The given prefix does not end with a period (" + prefix + ")");
Map<String, String> result = Maps.newHashMap();
synchronized (parameters) {
for (String key : parameters.keySet()) {
if (key.startsWith(prefix)) {
String name = key.substring(prefix.length());
result.put(name, parameters.get(key));
}
}
}
return ImmutableMap.copyOf(result);
}
解决方法
如果问题相同,可以直接使用我的编译好的jar包。
一、下载并解压
- 从Git开源项目flume-ng-sql-source上下载源码zip包
- 解压此zip包:(
unzip flume-ng-sql-source-develop.zip
)
- 进入解压后的文件夹(
cd flume-ng-sql-source-develop
),也就是进入到pom.xml所在的文件夹
二、配置Pom.xml文件
修改源码中的pom.xml文件:
- 添加CDH官方库:Maven中央仓库中缺少CDH的相关依赖包
<repositories>
<!-- 添加CDH官方库 -->
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
- 修改
flume-ng-core
的版本:需要使用CDH版本的flume,请从CDH仓库找到你所需要的版本,并修改下面的<version>。
<!-- 原本是1.8.0
<dependency>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-core</artifactId>
<version>1.8.0</version>
<scope>provided</scope>
</dependency>
-->
<dependency>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-core</artifactId>
<version>1.9.0-cdh6.2.1</version>
<scope>provided</scope>
</dependency>
三、编译得到jar包
-
在此文件夹下运行
mvn package
命令,maven将自动下载依赖jar包,并最终将此项目编译成一个jar
-
根据编译结果可知,编译后的jar包在target文件夹下:
-
这里的jar包就是编译后可供使用的jar包了,你可以自行修改 名字(当然可以在使用Eclipse编译指定jar包名字)。
四、将jar包放入flume/lib中
- 我的具体的目录的是:
/opt/cloudera/parcels/CDH/lib/flume-ng/lib
依次执行命令:
删除原来存在的flume-ng-sql-source-1.5.3.jar
cd /opt/cloudera/parcels/CDH/lib/flume-ng/lib
rm flume-ng-sql-source-1.5.3.jar
添加新编译的flume-ng-sql-source-1.5.3.jar
sudo cp ”你的jar路径“ /opt/cloudera/parcels/CDH/lib/flume-ng/lib
sudo chmod -R 777 flume-ng-sql-source-1.5.3.jar
五、重新执行flume任务
我经过以上修改编译之后没有问题。