java:解决SPI机制遇到的非典型问题-ServiceLoad.load(Class<T> service)方法失效

文章讲述了JavaSPI(ServiceProviderInterface)在Android平台上遇到的问题,即ServiceLoader.load()无法找到接口类的配置文件。作者发现这可能是由于客户项目中特定ClassLoader导致的,通过提供两种加载方式解决了问题。

Java SPI 的实现原理并不复杂,它的实现基于 Java 类加载机制和反射机制。
当使用 ServiceLoader.load(Class<T> service) 方法加载服务时,会检查 META-INF/services 目录下是否存在以接口全限定名命名的文件。如果存在,则读取文件内容,获取实现该接口的类的全限定名,并通过 Class.forName() 方法加载对应的类。

以下是我的项目中基于SPI加载接口实例的代码:

	/**
	 * SPI(Service Provider Interface)机制加载 {@link IRowMetaData}所有实例
	 * @return 表名和 {@link RowMetaData}实例的映射对象 
	 */
	private static HashMap<String, RowMetaData> loadRowMetaData() {		
		ServiceLoader<IRowMetaData> providers = ServiceLoader.load(IRowMetaData.class);
		Iterator<IRowMetaData> itor = providers.iterator();
		IRowMetaData instance;
		HashMap<String, RowMetaData> m = new HashMap<>();
		while(itor.hasNext()){
			try {
				instance = itor.next();				
			} catch (ServiceConfigurationError e) {
				// 实例初始化失败输出错误日志后继续循环
				SimpleLog.log(e.getMessage());
				continue;
			}
			if(instance instanceof RowMetaData){
				RowMetaData rowMetaData = (RowMetaData)instance;
				m.put(rowMetaData.tablename, rowMetaData);
			}
		}
		return m;
	}

这个代码写了几年了,在Windows,Linux,Android平台都没有任何问题。但最近在客户的设备上(Android)出了问题。
我们提供的DEMO程序在客户的设备上也能正常执行,但放在客户的项目代码中,就不行。
通过跟踪发现itor.hasNext()返回false,就导致没有执行循环,应该是没有找到META-INF/services 目录下接口IRowMetaData的全限定名命名的文件。

进一步跟踪,找到itor.hasNext()【java.util.ServiceLoader.LayIterator.hasNext()】最终调用的实现代码

        private boolean hasNextService() {
            if (nextName != null) {
                return true;
            }
            if (configs == null) {
                try {
                    String fullName = PREFIX + service.getName();
                    if (loader == null)
                        configs = ClassLoader.getSystemResources(fullName);
                    else
                        configs = loader.getResources(fullName);
                } catch (IOException x) {
                    fail(service, "Error locating configuration files", x);
                }
            }
            while ((pending == null) || !pending.hasNext()) {
                if (!configs.hasMoreElements()) {
                    return false;
                }
                pending = parse(service, configs.nextElement());
            }
            nextName = pending.next();
            return true;
        }

可以看到最终是通过调用ClassLoader.getResources(String)来读取META-INF/services 目录下接口类的全限定名命名的文件,根据ClassLoader.getResources(String)的方法说明,如果没有找到对应的文件,则返回空的对象。

所以itor.hasNext()返回false的直接原因应该就是没找到META-INF/services 目录下接口类的全限定名命名的文件。但是为什么会这样,没搞明白。
进一步看ServiceLoader的代码,才知道,ServiceLoader.load其实有两个重载方法,如下:

    public static <S> ServiceLoader<S> load(Class<S> service,
                                            ClassLoader loader)
    {
        return new ServiceLoader<>(service, loader);
    }
    public static <S> ServiceLoader<S> load(Class<S> service) {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        return ServiceLoader.load(service, cl);
    }

常用的ServiceLoader.load(Class<T> service)方法的实现其实是使用当前线程上下文的ClassLoader实例为参数调用了ServiceLoader.load(Class<T> service,ClassLoader loader)方法

于是我尝试改为调用ServiceLoader.load(Class<T> service,ClassLoader loader)方法,以接口类的ClassLoader实例作为loader参数,如下:

ServiceLoader<IRowMetaData> providers = ServiceLoader.load(IRowMetaData.class,IRowMetaData.class.getClassLoader());

居然可以正常执行了。

为什么会这样?太奇怪了,我无法解释,最有可能是的原因是客户的项目中的使用某种应用框架有自己的ClassLoader作为当前线程上下文的ClassLoader实例,.这个ClassLoader有BUG,找不到META-INF/services 目录下的资源文件。

不管怎样,为了安全起见,兼容两种加载方式,我将获取 实例迭代器(Iterator)的逻辑修改为如下:
即优先调用ServiceLoader.load(Class<T> service)如果返回空则调用ServiceLoader.load(Class<T> service,ClassLoader loader)方法

	/**
	 * SPI(Service Provider Interface)机制加载 {@link IRowMetaData}所有实例
	 * @return 表名和 {@link RowMetaData}实例的映射对象 
	 */
	private static HashMap<String, RowMetaData> loadRowMetaData() {		
		// 优先调用ServiceLoader.load(Class<T> service)
		// 如果返回空则调用ServiceLoader.load(Class<T> service,ClassLoader loader)方法
		Iterator<IRowMetaData> itor = ServiceLoader.load(IRowMetaData.class).iterator();
		if(!itor.hasNext()){
			itor = ServiceLoader.load(IRowMetaData.class,IRowMetaData.class.getClassLoader()).iterator();
		}
		IRowMetaData instance;
		HashMap<String, RowMetaData> m = new HashMap<>();
		while(itor.hasNext()){
			try {
				instance = itor.next();				
			} catch (ServiceConfigurationError e) {
				// 实例初始化失败输出错误日志后继续循环
				SimpleLog.log(e.getMessage());
				continue;
			}
			if(instance instanceof RowMetaData){
				RowMetaData rowMetaData = (RowMetaData)instance;
				m.put(rowMetaData.tablename, rowMetaData);
			}
		}
		return m;
	}

这个问题解决了,但感觉是莫名奇妙,我查了很多关于第三方库及JDK的源码,关于SPI的使用方式都是调用ServiceLoader.load(Class<T> service),很少有特别强制要调用ServiceLoader.load(Class<T> service,ClassLoader loader)方法,大家都是这么用的,到我这里却出了毛病,很难向客户证明这不是我们的问题。
好在可以通过修改我们代码,增加容错性逻辑解决了问题。

我的Dubbo Router功能完全不生效,我已经全部按照规范配置了: Router实现类: package com.htsc.gtp.quant.cm.domestic.router; import com.alibaba.dubbo.common.URL; import com.alibaba.dubbo.common.extension.Activate; import com.alibaba.dubbo.rpc.Invocation; import com.alibaba.dubbo.rpc.Invoker; import com.alibaba.dubbo.rpc.RpcException; import com.alibaba.dubbo.rpc.cluster.Router; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import static com.htsc.gtp.quant.cm.domestic.enums.StrategyCodeEnum.DOM_GRID_COND_ORDER; /** * @Project: gtp-quant-cm-domestic * @Author: 022679 * @CreateTime: 2025-08-20 15:00 * @Description: * @Version: **/ @Slf4j @Activate(group = {"provider"}) public class StraTransServiceRouter implements Router { public StraTransServiceRouter() { log.info("StraTransServiceRouter loaded successfully!"); } @Override public URL getUrl() { return null; } @Override public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException { log.info("Enter StraTransServiceRouter"); String interfaceName = invocation.getInvoker().getInterface().getName(); if ("ICondStraTransService".equals(interfaceName)) { Object[] args = invocation.getArguments(); if (args != null && args.length == 1) { String reqDtoJsonStr = JSON.toJSONString(args[0]); JSONObject reqDtoJsonObject = JSON.parseObject(reqDtoJsonStr); Integer strategyCode = reqDtoJsonObject.getInteger("strategyCode"); if (Objects.nonNull(strategyCode) && strategyCode.equals(DOM_GRID_COND_ORDER.getVal())) { // 网格策略大厅跟单请求,筛选Service注解group为gridHall的实现类 return invokers.stream().filter(tInvoker -> "gridHall".equals(tInvoker.getUrl().getParameter("group"))) .collect(Collectors.toList()); } else { // 非网格策略大厅跟单请求,筛选Service注解group不为gridHall的实现类 return invokers.stream().filter(tInvoker -> !"gridHall".equals(tInvoker.getUrl().getParameter("group"))) .collect(Collectors.toList()); } } } // 非ICondStraTransService接口,不做路由 return invokers; } @Override public int getPriority() { return 0; } @Override public int compareTo(Router o) { return 0; } } RouterFactory实现类: package com.htsc.gtp.quant.cm.domestic.router; import com.alibaba.dubbo.common.URL; import com.alibaba.dubbo.common.extension.Activate; import com.alibaba.dubbo.rpc.cluster.Router; import com.alibaba.dubbo.rpc.cluster.RouterFactory; import org.springframework.stereotype.Component; /** * @Project: gtp-quant-cm-domestic * @Author: 022679 * @CreateTime: 2025-08-20 18:16 * @Description: * @Version: **/ @Activate(group = {"provider"}) public class StraTransServiceRouterFactory implements RouterFactory { @Override public Router getRouter(URL url) { return new StraTransServiceRouter(); } } SPI配置: D:\JavaProject\gtp-quant\gtp-quant-cm-domestic\gtp-quant-cm-domestic-server\src\main\resources\META-INF\dubbo\com.alibaba.dubbo.rpc.cluster.Router straTransServiceRouter=com.htsc.gtp.quant.cm.domestic.router.StraTransServiceRouter D:\JavaProject\gtp-quant\gtp-quant-cm-domestic\gtp-quant-cm-domestic-server\src\main\resources\META-INF\dubbo\com.alibaba.dubbo.rpc.cluster.RouterFactory straTransServiceRouterFactory=com.htsc.gtp.quant.cm.domestic.router.StraTransServiceRouterFactory dubbo-config.xml: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 应用信息配置 --> <dubbo:application name="${dubbo.application.name}" owner="${dubbo.application.owner}" logger="${dubbo.application.logger}" /> <!-- 服务注册中心配置 --> <dubbo:registry id="dubbo_zookeeper" address="${dubbo.registry.address}" register="true" subscribe="true" check="false" file="${dubbo.application.name}" session="${dubbo.session.timeout}"/> <!-- 灰度服务注册中心配置 --> <dubbo:registry id="dubbo_grey_zookeeper" address="${dubbo.grey.registry.address}" register="true" subscribe="true" check="false" file="${dubbo.application.name}" session="${dubbo.session.timeout}"/> <!-- 监控中心配置 --> <!-- <dubbo:monitor protocol="${dubbo.monitor.protocol}" /> --> <!-- 服务协议&端口 --> <dubbo:protocol name="dubbo" port="${dubbo.dubbo.port}" /> <!-- dubbo:protocol name="dubbo" port="${dubbo.dubbo.port}" serialization="${dubbo.dubbo.serialization}" / --> <!-- 服务协议&端口 --> <dubbo:protocol name="rest" port="${dubbo.rest.port}" contextpath="${dubbo.rest.contextpath}" server="${dubbo.rest.server}" extension=""/> <!-- dubbo:service 默认配置 --> <dubbo:provider filter="rpcinfocollect,globalFilter,logFilter,traceFilter" validation="false" registry="dubbo_zookeeper" protocol="${dubbo.protocol}" payload="883886080" retries="${dubbo.retries}" timeout="${dubbo.session.timeout}" executes="${dubbo.executes}" actives="${dubbo.actives}" loadbalance="${dubbo.loadbalance}" threads="${dubbo.threads}" accepts="${dubbo.accepts}" /> <!-- dubbo:reference 默认配置 --> <dubbo:consumer filter="rpcinfocollect,traceFilter" validation="false" check="false" registry="dubbo_zookeeper" retries="${dubbo.retries}" timeout="${dubbo.session.timeout}" loadbalance="${dubbo.loadbalance}" /> <!-- 跨系统调用接口 --> <dubbo:reference id="custRegisterApi" interface="com.htsc.gtp.quant.cust.api.CustRegisterApi" version="1.0.0" registry="dubbo_zookeeper"/> <dubbo:reference id="acctManagerApi" interface="com.htsc.gtp.quant.cust.api.AcctManagerApi" version="1.0.0" registry="dubbo_zookeeper"/> <dubbo:reference id="equityManagerApi" interface="com.htsc.gtp.quant.cust.api.EquityManagerApi" version="1.0.0" registry="dubbo_zookeeper"/> <dubbo:reference id="abnormalCliQueryApi" interface="com.htsc.gtp.quant.cust.api.AbnormalCliQueryApi" version="1.0.0" registry="dubbo_zookeeper"/> <!--<dubbo:reference id="quantStaticInfoService" interface="com.htsc.gtp.pmdsproxy.api.QuantStaticInfoService" version="${prdt.dubbo.version}" registry="dubbo_zookeeper"/>--> <dubbo:reference id="strategyCondOrderQueryApi" interface="com.htsc.gtp.sem.dqs.api.StrategyCondOrderQueryApi" version="1.1.0" registry="dubbo_zookeeper"/> <dubbo:reference id="strategyCondOrderHisQueryApi" interface="com.htsc.gtp.sem.dqs.api.StrategyCondOrderHisQueryApi" version="1.1.0" registry="dubbo_zookeeper"/> <!--旧微服务dubbo接口--> <dubbo:reference id="oldMaQuantOrderService" interface = "com.htsc.uf.api.IMaQuantOrderService" version="1.1.8" registry="dubbo_grey_zookeeper"/> <dubbo:reference id="oldCondAcctService" interface = "com.htsc.uf.api.ICondAcctService" registry="dubbo_grey_zookeeper"/> <!-- 对外接口 --> <dubbo:service ref = "maQuantOrderService" interface = "com.htsc.gtp.quant.cm.domestic.api.IMaQuantOrderService" version="1.1.8" registry="dubbo_grey_zookeeper"/> <!-- <dubbo:service ref = "condOrdSuitService" interface = "com.htsc.uf.api.ICondOrdSuitService" version="1.1.8" />--> <dubbo:service ref = "condAcctService" interface = "com.htsc.gtp.quant.cm.domestic.api.ICondAcctService" registry="dubbo_grey_zookeeper"/> <!-- <dubbo:service ref = "maQuoteService" interface = "com.htsc.uf.api.IMaQuoteService" version="1.1.8" />--> <!-- <dubbo:service ref = "condOrdQryService" interface = "com.htsc.uf.api.ICondOrdQryService" version="1.1.8" /> --> <dubbo:service ref = "maManageService" interface = "com.htsc.gtp.quant.cm.domestic.api.IMaManageService" registry="dubbo_grey_zookeeper"/> <dubbo:service ref = "condStraTransServiceImpl" group="default" interface = "com.htsc.gtp.quant.cm.domestic.api.ICondStraTransService" registry="dubbo_grey_zookeeper"/> <bean id="condStraTransServiceImpl" class="com.htsc.gtp.quant.cm.domestic.api.impl.CondStraTransServiceImpl"/> <dubbo:service ref = "gridHallCondStraTransServiceImpl" group="gridHall" interface = "com.htsc.gtp.quant.cm.domestic.api.ICondStraTransService" registry="dubbo_grey_zookeeper"/> <bean id="gridHallCondStraTransServiceImpl" class="com.htsc.gtp.quant.cm.domestic.api.impl.GridHallCondStraTransServiceImpl"/> </beans>
08-22
JDK annotations not found Details: Paths checked: D:/android-studio/android-studio/plugins/java/lib/jdkAnnotations.jar; exists: true; siblings: [aether-api-1.1.0.jar, aether-connector-basic-1.1.0.jar, aether-dependency-resolver.jar, aether-impl-1.1.0.jar, aether-spi-1.1.0.jar, aether-transport-file-1.1.0.jar, aether-transport-http-1.1.0.jar, aether-util-1.1.0.jar, commons-lang3-3.4.jar, debugger-memory-agent-0.0.11.jar, ecj-4.10.jar, java-api.jar, java-impl.jar, javac2.jar, java_resources_en.jar, jdkAnnotations.jar, jgoodies-common-1.4.0.jar, jps-builders-6.jar, jps-builders.jar, jps-launcher.jar, jshell-protocol.jar, maven-aether-provider-3.3.9.jar, maven-artifact-3.3.9.jar, maven-builder-support-3.3.9.jar, maven-model-3.3.9.jar, maven-model-builder-3.3.9.jar, maven-repository-metadata-3.3.9.jar, plexus-component-annotations-1.6.jar, plexus-interpolation-1.21.jar, plexus-utils-3.0.22.jar, resources.jar, resources_en.jar, rt, wadl-core.jar] jar://D:/android-studio/android-studio/lib/jdkAnnotations.jar!/; exists: false; siblings: null D:/android-studio/android-studio/java/jdkAnnotations; exists: false; siblings: null com.intellij.openapi.diagnostic.Logger$EmptyThrowable at com.intellij.openapi.diagnostic.Logger.error(Logger.java:169) at com.intellij.openapi.projectRoots.impl.JavaSdkImpl.attachIDEAAnnotationsToJdk(JavaSdkImpl.java:279) at com.intellij.openapi.projectRoots.impl.JavaSdkImpl.attachJdkAnnotations(JavaSdkImpl.java:265) at com.intellij.openapi.projectRoots.impl.JavaSdkImpl.createJdk(JavaSdkImpl.java:369) at com.intellij.openapi.projectRoots.JavaSdk.createJdk(JavaSdk.java:21) at com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl.getInternalJdk(JavaAwareProjectJdkTableImpl.java:34) at com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl.loadState(JavaAwareProjectJdkTableImpl.java:60) at com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl.loadState(JavaAwareProjectJdkTableImpl.java:17) at com.intellij.configurationStore.ComponentStoreImpl.doInitComponent(ComponentStoreImpl.kt:405) at com.intellij.configurationStore.ComponentStoreImpl.initComponent(ComponentStoreImpl.kt:355) at com.intellij.configurationStore.ComponentStoreImpl.initPersistenceStateComponent(ComponentStoreImpl.kt:122) at com.intellij.configurationStore.ComponentStoreImpl.initComponent(ComponentStoreImpl.kt:97) at com.intellij.configurationStore.ComponentStoreWithExtraComponents.initComponent(ComponentStoreWithExtraComponents.kt:49) at com.intellij.openapi.components.impl.PlatformComponentManagerImpl.initializeComponent(PlatformComponentManagerImpl.java:44) at com.intellij.openapi.components.impl.ServiceManagerImpl$MyComponentAdapter.createAndInitialize(ServiceManagerImpl.java:248) at com.intellij.openapi.components.impl.ServiceManagerImpl$MyComponentAdapter.lambda$getComponentInstance$0(ServiceManagerImpl.java:232) at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:591) at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:537) at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:59) at com.intellij.openapi.progress.impl.CoreProgressManager.executeNonCancelableSection(CoreProgressManager.java:197) at com.intellij.openapi.components.impl.ServiceManagerImpl$MyComponentAdapter.getComponentInstance(ServiceManagerImpl.java:231) at com.intellij.util.pico.DefaultPicoContainer.getLocalInstance(DefaultPicoContainer.java:246) at com.intellij.util.pico.DefaultPicoContainer.getComponentInstance(DefaultPicoContainer.java:213) at com.intellij.openapi.components.ServiceManager.doGetService(ServiceManager.java:75) at com.intellij.openapi.components.ServiceManager.getService(ServiceManager.java:44) at com.intellij.openapi.projectRoots.ProjectJdkTable.getInstance(ProjectJdkTable.java:20) at com.android.tools.idea.sdk.AndroidSdks.getAllAndroidSdks(AndroidSdks.java:249) at com.android.tools.idea.sdk.IdeSdks.getEligibleAndroidSdks(IdeSdks.java:895) at com.android.tools.idea.sdk.IdeSdks.getFirstAndroidSdk(IdeSdks.java:393) at com.android.tools.idea.sdk.IdeSdks.getAndroidSdkPath(IdeSdks.java:129) at com.android.tools.idea.startup.AndroidSdkInitializer.run(AndroidSdkInitializer.java:80) at com.android.tools.idea.AndroidInitialConfigurator.activateAndroidStudioInitializerExtensions(AndroidInitialConfigurator.java:201) at com.android.tools.idea.AndroidInitialConfigurator.<init>(AndroidInitialConfigurator.java:71) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.picocontainer.defaults.InstantiatingComponentAdapter.newInstance(InstantiatingComponentAdapter.java:193) at com.intellij.util.pico.CachingConstructorInjectionComponentAdapter.doGetComponentInstance(CachingConstructorInjectionComponentAdapter.java:88) at com.intellij.util.pico.CachingConstructorInjectionComponentAdapter.instantiateGuarded(CachingConstructorInjectionComponentAdapter.java:66) at com.intellij.util.pico.CachingConstructorInjectionComponentAdapter.getComponentInstance(CachingConstructorInjectionComponentAdapter.java:48) at com.intellij.openapi.components.impl.ComponentManagerImpl$ComponentConfigComponentAdapter.getComponentInstance(ComponentManagerImpl.java:481) at com.intellij.openapi.components.impl.ComponentManagerImpl.createComponents(ComponentManagerImpl.java:126) at com.intellij.openapi.application.impl.ApplicationImpl.lambda$load$7(ApplicationImpl.java:414) at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:169) at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:591) at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:537) at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:59) at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:156) at com.intellij.openapi.application.impl.ApplicationImpl.load(ApplicationImpl.java:414) at com.intellij.idea.IdeaApplication.lambda$executeInitAppInEdt$5(IdeaApplication.java:153) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:764) at java.awt.EventQueue.access$500(EventQueue.java:98) at java.awt.EventQueue$3.run(EventQueue.java:715) at java.awt.EventQueue$3.run(EventQueue.java:709) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74) at java.awt.EventQueue.dispatchEvent(EventQueue.java:734) at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:438) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) 分析分享
06-20
025-03-16 21:26:18.516 [main] WARN Engine - prioriy set to 0, because NumberFormatException, the value is: null 2025-03-16 21:26:18.517 [main] INFO PerfTrace - PerfTrace traceId=job_-1, isEnable=false, priority=0 2025-03-16 21:26:18.517 [main] INFO JobContainer - DataX jobContainer starts job. 2025-03-16 21:26:18.519 [main] INFO JobContainer - Set jobId = 0 Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The dr iver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.2025-03-16 21:26:18.885 [job-0] INFO OriginalConfPretreatmentUtil - Available jdbcUrl:jdbc:mysql://master:3306/szt?y earIsDateType=false&zeroDateTimeBehavior=convertToNull&tinyInt1isBit=false&rewriteBatchedStatements=true.2025-03-16 21:26:18.913 [job-0] INFO OriginalConfPretreatmentUtil - table:[szt_data] has columns:[car_no,card_no,clo se_date,company_name,conn_mark,deal_date,deal_money,deal_type,deal_value,equ_no,station].三月 16, 2025 9:26:19 下午 org.apache.hadoop.util.NativeCodeLoader <clinit> 警告: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable 2025-03-16 21:26:19.553 [job-0] INFO JobContainer - jobContainer starts to do prepare ... 2025-03-16 21:26:19.553 [job-0] INFO JobContainer - DataX Reader.Job [mysqlreader] do prepare work . 2025-03-16 21:26:19.554 [job-0] INFO JobContainer - DataX Writer.Job [hdfswriter] do prepare work . 2025-03-16 21:26:19.623 [job-0] INFO HdfsWriter$Job - 由于您配置了writeMode append, 写入前不做清理工作, [/daas/ods/o ds_szt_data] 目录下写入相应文件名前缀 [part] 的文件2025-03-16 21:26:19.623 [job-0] INFO JobContainer - jobContainer starts to do split ... 2025-03-16 21:26:19.623 [job-0] INFO JobContainer - Job set Channel-Number to 2 channels. 2025-03-16 21:26:19.646 [job-0] INFO SingleTableSplitUtil - split pk [sql=SELECT MIN(equ_no),MAX(equ_no) FROM szt_da ta WHERE (date_format(deal_date,'%Y%m%d') ='${dt}' AND equ_no IS NOT
03-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值