embulk 0.6.21 → 0.6.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/build.gradle +27 -15
  4. data/embulk-core/build.gradle +17 -1
  5. data/embulk-core/src/main/java/org/embulk/EmbulkEmbed.java +216 -0
  6. data/embulk-core/src/main/java/org/embulk/EmbulkService.java +13 -7
  7. data/embulk-core/src/main/java/org/embulk/command/LiquidTemplate.java +8 -0
  8. data/embulk-core/src/main/java/org/embulk/command/Runner.java +63 -27
  9. data/embulk-core/src/main/java/org/embulk/config/ConfigLoader.java +5 -0
  10. data/embulk-core/src/main/java/org/embulk/config/DataSourceImpl.java +3 -3
  11. data/embulk-core/src/main/java/org/embulk/exec/ExecModule.java +1 -1
  12. data/embulk-core/src/main/java/org/embulk/exec/PooledBufferAllocator.java +3 -1
  13. data/embulk-core/src/main/java/org/embulk/guice/Bootstrap.java +150 -0
  14. data/embulk-core/src/main/java/org/embulk/guice/CloseableInjector.java +22 -0
  15. data/embulk-core/src/main/java/org/embulk/guice/CloseableInjectorProxy.java +47 -0
  16. data/embulk-core/src/main/java/org/embulk/guice/InjectorProxy.java +145 -0
  17. data/embulk-core/src/main/java/org/embulk/guice/LifeCycleManager.java +187 -0
  18. data/embulk-core/src/main/java/org/embulk/guice/LifeCycleMethods.java +89 -0
  19. data/embulk-core/src/main/java/org/embulk/guice/LifeCycleMethodsMap.java +38 -0
  20. data/embulk-core/src/main/java/org/embulk/guice/LifeCycleModule.java +97 -0
  21. data/embulk-core/src/main/java/org/embulk/spi/TempFileSpace.java +41 -7
  22. data/embulk-docs/build.gradle +3 -2
  23. data/embulk-docs/src/built-in.rst +30 -1
  24. data/embulk-docs/src/index.rst +1 -1
  25. data/embulk-docs/src/release.rst +1 -0
  26. data/embulk-docs/src/release/release-0.6.22.rst +26 -0
  27. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  28. data/gradle/wrapper/gradle-wrapper.properties +2 -2
  29. data/lib/embulk/command/embulk_run.rb +11 -5
  30. data/lib/embulk/data_source.rb +28 -8
  31. data/lib/embulk/error.rb +7 -1
  32. data/lib/embulk/gems.rb +29 -0
  33. data/lib/embulk/java/bootstrap.rb +4 -0
  34. data/lib/embulk/java/liquid_helper.rb +17 -0
  35. data/lib/embulk/version.rb +1 -1
  36. data/test/helper.rb +11 -2
  37. metadata +46 -33
@@ -26,6 +26,11 @@ public class ConfigLoader
26
26
  this.model = model;
27
27
  }
28
28
 
29
+ public ConfigSource newConfigSource()
30
+ {
31
+ return new DataSourceImpl(model);
32
+ }
33
+
29
34
  public ConfigSource fromJsonFile(File file) throws IOException
30
35
  {
31
36
  try (FileInputStream is = new FileInputStream(file)) {
@@ -123,7 +123,7 @@ public class DataSourceImpl
123
123
  if (v == null) {
124
124
  remove(attrName);
125
125
  } else {
126
- data.put(attrName, model.writeObjectAsJsonNode(v));
126
+ data.set(attrName, model.writeObjectAsJsonNode(v));
127
127
  }
128
128
  return this;
129
129
  }
@@ -131,7 +131,7 @@ public class DataSourceImpl
131
131
  @Override
132
132
  public DataSourceImpl setNested(String attrName, DataSource v)
133
133
  {
134
- data.put(attrName, v.getObjectNode());
134
+ data.set(attrName, v.getObjectNode());
135
135
  return this;
136
136
  }
137
137
 
@@ -139,7 +139,7 @@ public class DataSourceImpl
139
139
  public DataSourceImpl setAll(DataSource other)
140
140
  {
141
141
  for (Map.Entry<String, JsonNode> field : other.getAttributes()) {
142
- data.put(field.getKey(), field.getValue());
142
+ data.set(field.getKey(), field.getValue());
143
143
  }
144
144
  return this;
145
145
  }
@@ -27,7 +27,7 @@ public class ExecModule
27
27
  {
28
28
  Preconditions.checkNotNull(binder, "binder is null.");
29
29
 
30
- binder.bind(ILoggerFactory.class).toProvider(LoggerProvider.class);
30
+ binder.bind(ILoggerFactory.class).toProvider(LoggerProvider.class).in(Scopes.SINGLETON);
31
31
  binder.bind(ModelManager.class).in(Scopes.SINGLETON);
32
32
  binder.bind(BufferAllocator.class).to(PooledBufferAllocator.class).in(Scopes.SINGLETON);
33
33
  binder.bind(TempFileAllocator.class).in(Scopes.SINGLETON);
@@ -3,6 +3,8 @@ package org.embulk.exec;
3
3
  import io.netty.buffer.PooledByteBufAllocator;
4
4
  import io.netty.buffer.ByteBuf;
5
5
  import io.netty.util.ResourceLeakDetector;
6
+ import io.netty.util.internal.logging.InternalLoggerFactory;
7
+ import io.netty.util.internal.logging.JdkLoggerFactory;
6
8
  import org.embulk.spi.Buffer;
7
9
  import org.embulk.spi.BufferAllocator;
8
10
  import com.google.inject.Inject;
@@ -18,7 +20,7 @@ public class PooledBufferAllocator
18
20
  private final int pageSize;
19
21
 
20
22
  @Inject
21
- public PooledBufferAllocator(@ForSystemConfig ConfigSource systemConfig)
23
+ public PooledBufferAllocator(@ForSystemConfig ConfigSource systemConfig, org.slf4j.ILoggerFactory factory)
22
24
  {
23
25
  this.nettyBuffer = new PooledByteBufAllocator(false);
24
26
  this.pageSize = systemConfig.get(ByteSize.class, "page_size", new ByteSize(DEFAULT_PAGE_SIZE)).getBytesInt();
@@ -0,0 +1,150 @@
1
+ /*
2
+ * Copyright 2015 Sadayuki Furuhashi
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ package org.embulk.guice;
17
+
18
+ import com.google.common.base.Function;
19
+ import com.google.common.collect.ImmutableList;
20
+ import com.google.common.collect.Iterables;
21
+ import com.google.common.annotations.Beta;
22
+
23
+ import com.google.inject.Binder;
24
+ import com.google.inject.Guice;
25
+ import com.google.inject.Module;
26
+ import com.google.inject.Stage;
27
+ import com.google.inject.Injector;
28
+ import java.util.Arrays;
29
+ import java.util.List;
30
+
31
+ @Beta
32
+ public class Bootstrap
33
+ {
34
+ private List<Module> modules;
35
+
36
+ private boolean requireExplicitBindings = true;
37
+
38
+ private boolean started;
39
+
40
+ public Bootstrap(Module... modules)
41
+ {
42
+ this(Arrays.asList(modules));
43
+ }
44
+
45
+ public Bootstrap(Iterable<? extends Module> modules)
46
+ {
47
+ this.modules = ImmutableList.copyOf(modules);
48
+ }
49
+
50
+ public Bootstrap requireExplicitBindings(boolean requireExplicitBindings)
51
+ {
52
+ this.requireExplicitBindings = requireExplicitBindings;
53
+ return this;
54
+ }
55
+
56
+ public Bootstrap addModules(Module... additionalModules)
57
+ {
58
+ return addModules(Arrays.asList(additionalModules));
59
+ }
60
+
61
+ public Bootstrap addModules(Iterable<? extends Module> additionalModules)
62
+ {
63
+ modules = ImmutableList.copyOf(Iterables.concat(modules, additionalModules));
64
+ return this;
65
+ }
66
+
67
+ //public Bootstrap onPreDestroy()
68
+ //{
69
+ //}
70
+
71
+ //public Bootstrap onPreDestroyException()
72
+ //{
73
+ //}
74
+
75
+ //public Bootstrap onStop()
76
+ //{
77
+ //}
78
+
79
+ //public Bootstrap forEachModule(Consumer<? super Module> function)
80
+ //{
81
+ // for (Module module : modules) {
82
+ // function.accept(module);
83
+ // }
84
+ // return this;
85
+ //}
86
+
87
+ //public <T> Bootstrap forEachModule(Class<T> ifClass, Consumer<? super T> function)
88
+ //{
89
+ // for (Module module : modules) {
90
+ // if (ifClass.instance(module) {
91
+ // function.accept(module);
92
+ // }
93
+ // }
94
+ // return this;
95
+ //}
96
+
97
+ public Bootstrap overrideModules(Function<? super List<Module>, ? extends Iterable<? extends Module>> function)
98
+ {
99
+ modules = ImmutableList.copyOf(function.apply(modules));
100
+ return this;
101
+ }
102
+
103
+ public Injector initialize()
104
+ {
105
+ Injector injector = start();
106
+ injector.getInstance(LifeCycleManager.class).destroyOnShutdownHook();
107
+ return injector;
108
+ }
109
+
110
+ public CloseableInjector initializeCloseable()
111
+ {
112
+ Injector injector = start();
113
+ return new CloseableInjectorProxy(injector, injector.getInstance(LifeCycleManager.class));
114
+ }
115
+
116
+ private Injector start()
117
+ {
118
+ if (started) {
119
+ throw new IllegalStateException("System already initialized");
120
+ }
121
+ started = true;
122
+
123
+ ImmutableList.Builder<Module> moduleList = ImmutableList.builder();
124
+
125
+ moduleList.addAll(modules);
126
+
127
+ moduleList.add(new Module()
128
+ {
129
+ @Override
130
+ public void configure(Binder binder)
131
+ {
132
+ binder.disableCircularProxies();
133
+ if (requireExplicitBindings) {
134
+ binder.requireExplicitBindings();
135
+ }
136
+ }
137
+ });
138
+
139
+ moduleList.add(new LifeCycleModule());
140
+
141
+ Injector injector = Guice.createInjector(Stage.PRODUCTION, moduleList.build());
142
+
143
+ LifeCycleManager lifeCycleManager = injector.getInstance(LifeCycleManager.class);
144
+ if (lifeCycleManager.size() > 0) {
145
+ lifeCycleManager.start();
146
+ }
147
+
148
+ return injector;
149
+ }
150
+ }
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Copyright 2015 Sadayuki Furuhashi
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ package org.embulk.guice;
17
+
18
+ import com.google.inject.Injector;
19
+
20
+ public interface CloseableInjector
21
+ extends Injector, AutoCloseable
22
+ { }
@@ -0,0 +1,47 @@
1
+ /*
2
+ * Copyright 2015 Sadayuki Furuhashi
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ package org.embulk.guice;
17
+
18
+ import com.google.inject.Injector;
19
+
20
+ class CloseableInjectorProxy
21
+ extends InjectorProxy
22
+ implements CloseableInjector
23
+ {
24
+ private final Injector injector;
25
+ private final LifeCycleManager lifeCycleManager;
26
+
27
+ public CloseableInjectorProxy(Injector injector, LifeCycleManager lifeCycleManager)
28
+ {
29
+ this.injector = injector;
30
+ this.lifeCycleManager = lifeCycleManager;
31
+ }
32
+
33
+ @Override
34
+ protected synchronized Injector injector()
35
+ {
36
+ if (lifeCycleManager.isDestroyed()) {
37
+ throw new IllegalStateException("Injector already closed");
38
+ }
39
+ return injector;
40
+ }
41
+
42
+ @Override
43
+ public synchronized void close() throws Exception
44
+ {
45
+ lifeCycleManager.destroy(); // reentrant
46
+ }
47
+ }
@@ -0,0 +1,145 @@
1
+ /*
2
+ * Copyright 2015 Sadayuki Furuhashi
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ package org.embulk.guice;
17
+
18
+ import com.google.inject.Binding;
19
+ import com.google.inject.Injector;
20
+ import com.google.inject.Key;
21
+ import com.google.inject.MembersInjector;
22
+ import com.google.inject.Module;
23
+ import com.google.inject.Provider;
24
+ import com.google.inject.Scope;
25
+ import com.google.inject.TypeLiteral;
26
+ import com.google.inject.spi.TypeConverterBinding;
27
+
28
+ import java.lang.annotation.Annotation;
29
+ import java.util.List;
30
+ import java.util.Map;
31
+ import java.util.Set;
32
+
33
+ abstract class InjectorProxy
34
+ implements Injector
35
+ {
36
+ protected abstract Injector injector();
37
+
38
+ @Override
39
+ public void injectMembers(Object instance)
40
+ {
41
+ injector().injectMembers(instance);
42
+ }
43
+
44
+ @Override
45
+ public <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> typeLiteral)
46
+ {
47
+ return injector().getMembersInjector(typeLiteral);
48
+ }
49
+
50
+ @Override
51
+ public <T> MembersInjector<T> getMembersInjector(Class<T> type)
52
+ {
53
+ return injector().getMembersInjector(type);
54
+ }
55
+
56
+ @Override
57
+ public Map<Key<?>, Binding<?>> getBindings()
58
+ {
59
+ return injector().getBindings();
60
+ }
61
+
62
+ @Override
63
+ public Map<Key<?>, Binding<?>> getAllBindings()
64
+ {
65
+ return injector().getAllBindings();
66
+ }
67
+
68
+ @Override
69
+ public <T> Binding<T> getBinding(Key<T> key)
70
+ {
71
+ return injector().getBinding(key);
72
+ }
73
+
74
+ @Override
75
+ public <T> Binding<T> getBinding(Class<T> type)
76
+ {
77
+ return injector().getBinding(type);
78
+ }
79
+
80
+ @Override
81
+ public <T> Binding<T> getExistingBinding(Key<T> key)
82
+ {
83
+ return injector().getExistingBinding(key);
84
+ }
85
+
86
+ @Override
87
+ public <T> List<Binding<T>> findBindingsByType(TypeLiteral<T> type)
88
+ {
89
+ return injector().findBindingsByType(type);
90
+ }
91
+
92
+ @Override
93
+ public <T> Provider<T> getProvider(Key<T> key)
94
+ {
95
+ return injector().getProvider(key);
96
+ }
97
+
98
+ @Override
99
+ public <T> Provider<T> getProvider(Class<T> type)
100
+ {
101
+ return injector().getProvider(type);
102
+ }
103
+
104
+ @Override
105
+ public <T> T getInstance(Key<T> key)
106
+ {
107
+ return injector().getInstance(key);
108
+ }
109
+
110
+ @Override
111
+ public <T> T getInstance(Class<T> type)
112
+ {
113
+ return injector().getInstance(type);
114
+ }
115
+
116
+ @Override
117
+ public Injector getParent()
118
+ {
119
+ return injector().getParent();
120
+ }
121
+
122
+ @Override
123
+ public Injector createChildInjector(Iterable<? extends Module> modules)
124
+ {
125
+ return injector().createChildInjector(modules);
126
+ }
127
+
128
+ @Override
129
+ public Injector createChildInjector(Module... modules)
130
+ {
131
+ return injector().createChildInjector(modules);
132
+ }
133
+
134
+ @Override
135
+ public Map<Class<? extends Annotation>, Scope> getScopeBindings()
136
+ {
137
+ return injector().getScopeBindings();
138
+ }
139
+
140
+ @Override
141
+ public Set<TypeConverterBinding> getTypeConverterBindings()
142
+ {
143
+ return injector().getTypeConverterBindings();
144
+ }
145
+ }
@@ -0,0 +1,187 @@
1
+ /*
2
+ * Copyright 2010 Proofpoint, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /*
17
+ * Copyright 2015 Sadayuki Furuhashi
18
+ */
19
+ package org.embulk.guice;
20
+
21
+ import com.google.common.collect.Lists;
22
+
23
+ import javax.annotation.PostConstruct;
24
+ import javax.annotation.PreDestroy;
25
+ import java.lang.reflect.InvocationTargetException;
26
+ import java.lang.reflect.Method;
27
+ import java.util.Collections;
28
+ import java.util.List;
29
+ import java.util.Queue;
30
+ import java.util.concurrent.ConcurrentLinkedQueue;
31
+ import java.util.concurrent.atomic.AtomicReference;
32
+
33
+ /**
34
+ * Manages PostConstruct and PreDestroy life cycles
35
+ */
36
+ public final class LifeCycleManager
37
+ {
38
+ private final AtomicReference<State> state = new AtomicReference<State>(State.LATENT);
39
+ private final Queue<Object> managedInstances = new ConcurrentLinkedQueue<Object>();
40
+ private final LifeCycleMethodsMap methodsMap;
41
+
42
+ private enum State
43
+ {
44
+ LATENT,
45
+ STARTING,
46
+ STARTED,
47
+ STOPPING,
48
+ STOPPED
49
+ }
50
+
51
+ /**
52
+ * @param managedInstances list of objects that have life cycle annotations
53
+ * @param methodsMap existing or new methods map
54
+ * @throws Exception exceptions starting instances (depending on mode)
55
+ */
56
+ public LifeCycleManager(List<Object> managedInstances, LifeCycleMethodsMap methodsMap)
57
+ throws Exception
58
+ {
59
+ this.methodsMap = (methodsMap != null) ? methodsMap : new LifeCycleMethodsMap();
60
+ for (Object instance : managedInstances) {
61
+ addInstance(instance);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Returns the number of managed instances
67
+ *
68
+ * @return qty
69
+ */
70
+ public int size()
71
+ {
72
+ return managedInstances.size();
73
+ }
74
+
75
+ /**
76
+ * Start the life cycle - all instances will have their {@link javax.annotation.PostConstruct} method(s) called
77
+ *
78
+ * @throws Exception errors
79
+ */
80
+ public void start()
81
+ {
82
+ if (!state.compareAndSet(State.LATENT, State.STARTING)) {
83
+ throw new IllegalStateException("System already starting");
84
+ }
85
+ //log.info("Life cycle starting...");
86
+
87
+ for (Object obj : managedInstances) {
88
+ LifeCycleMethods methods = methodsMap.get(obj.getClass());
89
+ if (!methods.hasFor(PreDestroy.class)) {
90
+ managedInstances.remove(obj); // remove reference to instances that aren't needed anymore
91
+ }
92
+ }
93
+
94
+ state.set(State.STARTED);
95
+ //log.info("Life cycle startup complete. System ready.");
96
+ }
97
+
98
+ /**
99
+ * Add a shutdown hook that calls {@link destroy} method
100
+ */
101
+ public void destroyOnShutdownHook()
102
+ {
103
+ Runtime.getRuntime().addShutdownHook(new Thread()
104
+ {
105
+ @Override
106
+ public void run()
107
+ {
108
+ try {
109
+ LifeCycleManager.this.destroy();
110
+ }
111
+ catch (Exception e) {
112
+ //log.error(e, "Trying to shut down");
113
+ }
114
+ }
115
+ });
116
+ }
117
+
118
+ /**
119
+ * Stop the life cycle - all instances will have their {@link javax.annotation.PreDestroy} method(s) called
120
+ *
121
+ * @throws Exception errors
122
+ */
123
+ public void destroy()
124
+ throws Exception
125
+ {
126
+ if (!state.compareAndSet(State.STARTED, State.STOPPING)) {
127
+ return;
128
+ }
129
+
130
+ //log.info("Life cycle stopping...");
131
+
132
+ List<Object> reversedInstances = Lists.newArrayList(managedInstances);
133
+ Collections.reverse(reversedInstances);
134
+
135
+ for (Object obj : reversedInstances) {
136
+ //log.debug("Stopping %s", obj.getClass().getName());
137
+ LifeCycleMethods methods = methodsMap.get(obj.getClass());
138
+ for (Method preDestroy : methods.methodsFor(PreDestroy.class)) {
139
+ //log.debug("\t%s()", preDestroy.getName());
140
+ preDestroy.invoke(obj);
141
+ }
142
+ }
143
+
144
+ state.set(State.STOPPED);
145
+ //log.info("Life cycle stopped.");
146
+ }
147
+
148
+ /**
149
+ * Return true if state is {@link destroy} is called
150
+ */
151
+ public boolean isDestroyed()
152
+ {
153
+ State currentState = state.get();
154
+ return currentState == State.STOPPING || currentState == State.STOPPED;
155
+ }
156
+
157
+ /**
158
+ * Add an additional managed instance
159
+ *
160
+ * @param instance instance to add
161
+ * @throws Exception errors
162
+ */
163
+ public void addInstance(Object instance)
164
+ throws Exception
165
+ {
166
+ if (isDestroyed()) {
167
+ throw new IllegalStateException("System already stopped");
168
+ }
169
+ else {
170
+ startInstance(instance);
171
+ if (methodsMap.get(instance.getClass()).hasFor(PreDestroy.class)) {
172
+ managedInstances.add(instance);
173
+ }
174
+ }
175
+ }
176
+
177
+ private void startInstance(Object obj)
178
+ throws IllegalAccessException, InvocationTargetException
179
+ {
180
+ //log.debug("Starting %s", obj.getClass().getName());
181
+ LifeCycleMethods methods = methodsMap.get(obj.getClass());
182
+ for (Method postConstruct : methods.methodsFor(PostConstruct.class)) {
183
+ //log.debug("\t%s()", postConstruct.getName());
184
+ postConstruct.invoke(obj);
185
+ }
186
+ }
187
+ }