7
7
import com .alibaba .datax .core .util .container .CoreConstant ;
8
8
9
9
import java .io .File ;
10
+ import java .io .IOException ;
10
11
import java .net .URL ;
11
12
import java .nio .file .Paths ;
12
- import java .util .HashMap ;
13
- import java .util .Map ;
13
+ import java .util .*;
14
14
15
15
/**
16
16
* @author fuyouj
@@ -44,9 +44,15 @@ private static Configuration parsePluginsConfig(Map<String, String> pluginTypeMa
44
44
45
45
Configuration configuration = Configuration .newDefault ();
46
46
47
- String workingDirectory = System .getProperty ("user.dir" );
48
- File file = new File (workingDirectory );
49
- scanPlugin (configuration , file .listFiles (), pluginTypeMap );
47
+ //最初打算通过user.dir获取工作目录来扫描插件,
48
+ //但是user.dir在不同有一些不确定性,所以废弃了这个选择
49
+
50
+ for (File basePackage : runtimeBasePackages ()) {
51
+ if (pluginTypeMap .isEmpty ()) {
52
+ break ;
53
+ }
54
+ scanPluginByPackage (basePackage , configuration , basePackage .listFiles (), pluginTypeMap );
55
+ }
50
56
if (!pluginTypeMap .isEmpty ()) {
51
57
throw DataXException .asDataXException (FrameworkErrorCode .PLUGIN_INIT_ERROR ,
52
58
"load plugin failed,未完成指定插件加载:"
@@ -55,7 +61,42 @@ private static Configuration parsePluginsConfig(Map<String, String> pluginTypeMa
55
61
return configuration ;
56
62
}
57
63
58
- private static void scanPlugin (Configuration configuration , File [] files , Map <String , String > pluginTypeMap ) {
64
+ /**
65
+ * 通过classLoader获取程序编译的输出目录
66
+ * @return File[/datax-example/target/classes,xxReader/target/classes,xxWriter/target/classes]
67
+ */
68
+ private static File [] runtimeBasePackages () {
69
+ List <File > basePackages = new ArrayList <>();
70
+ ClassLoader classLoader = Thread .currentThread ().getContextClassLoader ();
71
+ Enumeration <URL > resources = null ;
72
+ try {
73
+ resources = classLoader .getResources ("" );
74
+ } catch (IOException e ) {
75
+ throw DataXException .asDataXException (e .getMessage ());
76
+ }
77
+
78
+ while (resources .hasMoreElements ()) {
79
+ URL resource = resources .nextElement ();
80
+ File file = new File (resource .getFile ());
81
+ if (file .isDirectory ()) {
82
+ basePackages .add (file );
83
+ }
84
+ }
85
+
86
+ return basePackages .toArray (new File [0 ]);
87
+ }
88
+
89
+ /**
90
+ *
91
+ * @param packageFile 编译出来的target/classes根目录 便于找到插件时设置插件的URL目录,设置根目录是最保险的方式
92
+ * @param configuration pluginConfig
93
+ * @param files 待扫描文件
94
+ * @param needPluginTypeMap 需要的插件
95
+ */
96
+ private static void scanPluginByPackage (File packageFile ,
97
+ Configuration configuration ,
98
+ File [] files ,
99
+ Map <String , String > needPluginTypeMap ) {
59
100
if (files == null ) {
60
101
return ;
61
102
}
@@ -64,22 +105,26 @@ private static void scanPlugin(Configuration configuration, File[] files, Map<St
64
105
Configuration pluginDesc = Configuration .from (file );
65
106
String descPluginName = pluginDesc .getString ("name" , "" );
66
107
67
- if (pluginTypeMap .containsKey (descPluginName )) {
108
+ if (needPluginTypeMap .containsKey (descPluginName )) {
68
109
69
- String type = pluginTypeMap .get (descPluginName );
70
- configuration .merge (parseOnePlugin (type , descPluginName , pluginDesc ), false );
71
- pluginTypeMap .remove (descPluginName );
110
+ String type = needPluginTypeMap .get (descPluginName );
111
+ configuration .merge (parseOnePlugin (packageFile . getAbsolutePath (), type , descPluginName , pluginDesc ), false );
112
+ needPluginTypeMap .remove (descPluginName );
72
113
73
114
}
74
115
} else {
75
- scanPlugin ( configuration , file .listFiles (), pluginTypeMap );
116
+ scanPluginByPackage ( packageFile , configuration , file .listFiles (), needPluginTypeMap );
76
117
}
77
118
}
78
119
}
79
120
80
- private static Configuration parseOnePlugin (String pluginType , String pluginName , Configuration pluginDesc ) {
81
121
82
- pluginDesc .set ("loadType" ,"pluginLoader" );
122
+ private static Configuration parseOnePlugin (String packagePath ,
123
+ String pluginType ,
124
+ String pluginName ,
125
+ Configuration pluginDesc ) {
126
+ //设置path 兼容jarLoader的加载方式URLClassLoader
127
+ pluginDesc .set ("path" , packagePath );
83
128
Configuration pluginConfInJob = Configuration .newDefault ();
84
129
pluginConfInJob .set (
85
130
String .format ("plugin.%s.%s" , pluginType , pluginName ),
0 commit comments