@@ -78,11 +78,11 @@ static ObjectNode rebuildObjectNode(final DataSource source) throws IOException
78
78
final JsonNode jsonNode = SIMPLE_MAPPER .readTree (jsonString .get ());
79
79
80
80
if (jsonNode == null ) {
81
- throw new NullPointerException ("DataSource#toJson() returned null." );
81
+ throw new NullPointerException ("DataSource(Impl) #toJson() returned null." );
82
82
}
83
83
if (!jsonNode .isObject ()) {
84
84
throw new ClassCastException (
85
- "DataSource#toJson() returned not a JSON object: " + jsonNode .getClass ().getCanonicalName ());
85
+ "DataSource(Impl) #toJson() returned not a JSON object: " + jsonNode .getClass ().getCanonicalName ());
86
86
}
87
87
return (ObjectNode ) jsonNode ;
88
88
}
@@ -95,7 +95,7 @@ static ObjectNode rebuildObjectNode(final DataSource source) throws IOException
95
95
}
96
96
97
97
private static Optional <String > callToJsonIfAvailable (final DataSource source ) {
98
- final Method toJson = getToJsonMethod ();
98
+ final Method toJson = getToJsonMethod (source );
99
99
if (toJson == null ) {
100
100
return Optional .empty ();
101
101
}
@@ -111,19 +111,19 @@ private static Optional<String> callToJsonIfAvailable(final DataSource source) {
111
111
if (targetException instanceof Error ) {
112
112
throw (Error ) targetException ;
113
113
}
114
- throw new IllegalStateException ("DataSource#toJson() threw unexpected Exception." , targetException );
114
+ throw new IllegalStateException ("DataSource(Impl) #toJson() threw unexpected Exception." , targetException );
115
115
} catch (final IllegalAccessException ex ) {
116
- logger .debug ("DataSource#toJson is not accessible unexpectedly. DataSource: {}, toJson: {}, " ,
116
+ logger .debug ("DataSource(Impl) #toJson is not accessible unexpectedly. DataSource: {}, toJson: {}, " ,
117
117
source .getClass (), toJson );
118
- throw new IllegalStateException ("DataSource#toJson() is not accessible." , ex );
118
+ throw new IllegalStateException ("DataSource(Impl) #toJson() is not accessible." , ex );
119
119
}
120
120
121
121
if (jsonStringObject == null ) {
122
- throw new NullPointerException ("org.embulk.config. DataSource#toJson() returned null." );
122
+ throw new NullPointerException ("DataSource(Impl) #toJson() returned null." );
123
123
}
124
124
if (!(jsonStringObject instanceof String )) {
125
125
throw new ClassCastException (
126
- "org.embulk.config. DataSource#toJson() returned not a String: "
126
+ "DataSource(Impl) #toJson() returned not a String: "
127
127
+ jsonStringObject .getClass ().getCanonicalName ());
128
128
}
129
129
@@ -163,7 +163,7 @@ private static ObjectNode callGetObjectNodeAndRebuildIfAvailable(final DataSourc
163
163
return ObjectNodeRebuilder .rebuild (coreObjectNode , mapper );
164
164
}
165
165
166
- private static Method getToJsonMethod () {
166
+ private static Method getToJsonMethod (final DataSource source ) {
167
167
try {
168
168
// Getting the "toJson" method from embulk-api's public interface "org.embulk.config.DataSource", not from an implementation class,
169
169
// for example "org.embulk.(util.)config.DataSourceImpl", so that invoking the method does not throw IllegalAccessException.
@@ -178,7 +178,27 @@ private static Method getToJsonMethod() {
178
178
// A method instance retrieved from the public interface "org.embulk.config.DataSource" would solve the problem.
179
179
return DataSource .class .getMethod ("toJson" );
180
180
} catch (final NoSuchMethodException ex ) {
181
- // Expected: toJson is not defined in Embulk v0.10.2 or earlier.
181
+ // Expected: toJson is not defined in "org.embulk.config.DataSource" when a user is running
182
+ // Embulk v0.10.2 or earlier.
183
+ //
184
+ // Even in the case, the received DataSource instance can still be of embulk-util-config's
185
+ // "org.embulk.util.config.DataSourceImpl" from another plugin (ex. input <=> parser), or
186
+ // from itself. As "org.embulk.util.config.DataSourceImpl" does not have "getObjectNode",
187
+ // it must still be rebuilt with "toJson" retrieved in some way.
188
+ //
189
+ // Pass-through to the next trial to retrieve the "toJson" method, then.
190
+ }
191
+
192
+ final Class <? extends DataSource > dataSourceImplClass = source .getClass ();
193
+ try {
194
+ // Getting the "toJson" method from the implementation class embulk-core's "org.embulk.config.DataSourceImpl",
195
+ // or embulk-util-config's "org.embulk.util.config.DataSourceImpl".
196
+ return dataSourceImplClass .getMethod ("toJson" );
197
+ } catch (final NoSuchMethodException ex ) {
198
+ // Still expected: toJson is not defined in embulk-core's "org.embulk.config.DataSourceImpl"
199
+ // in Embulk v0.10.2 or earlier.
200
+ //
201
+ // Returning null in this case so that it fallbacks to call the "getObjectNode" method instead.
182
202
return null ;
183
203
}
184
204
}
0 commit comments