apache / shardingsphere-elasticjob

Distributed scheduled job
Apache License 2.0
8.12k stars 3.28k forks source link

SpringProxyJobClassNameProvider may cause job conflicts in non proxy mode #2012

Open BertOnline opened 2 years ago

BertOnline commented 2 years ago

Bug Report

Which version of ElasticJob did you use?

3.0.1

Which project did you use? ElasticJob-Lite or ElasticJob-Cloud?

ElasticJob-Lite

Expected behavior

Job registration succeeded

Actual behavior

Job conflict with register center. The job 'test' in register center's class is 'com.test.elasticjob.CustomJob$$Lambda$1124/0x0000000800a5d440', your job class is 'com.test.elasticjob.CustomJob$$Lambda$1111/0x0000000800a60440'

Reason analyze (If you can)

Code causing the problem:

@Component
public class CustomJob {

    private static final int SINGLE_SHARDING_TOTAL_COUNT = 1;

    @Autowired
    private ZookeeperRegistryCenter zookeeperRegistryCenter;

    public void customJob() {
        JobConfiguration jobConfig = JobConfiguration
                .newBuilder("test", SINGLE_SHARDING_TOTAL_COUNT)
                .jobParameter("")
                .cron("0 30 2 ? * *")
                .overwrite(true)
                .jobShardingStrategyType("ROUND_ROBIN")
                .monitorExecution(true)
                .failover(true)
                .build();
        new ScheduleJobBootstrap(zookeeperRegistryCenter, (SimpleJob) shardingContext -> System.out.println("test"), jobConfig).schedule();
    }

}

Wrong location in source code:

@Slf4j
public final class SpringProxyJobClassNameProvider implements JobClassNameProvider {

    public SpringProxyJobClassNameProvider() {
        log.info("create SpringProxyJobClassNameProvider");
    }

    @Override
    public String getJobClassName(final ElasticJob elasticJob) {
        return AopUtils.isAopProxy(elasticJob) ? AopTargetUtils.getTarget(elasticJob).getClass().getName() : elasticJob.getClass().getName();
    }
}

When I create a SimpleJob using an anonymous inner class or lambda expression, if AopUtils.isAopProxy(elasticJob) == true, and return elasticJob.getClass().getName(), it will cause a job conflict with ZK. For the solution,when AopUtils.isAopProxy(elasticJob) == true, please refer to org.apache.shardingsphere.elasticjob.lite.internal.setup.DefaultJobClassNameProvider#getJobClassName

    @Override
    public String getJobClassName(final ElasticJob elasticJob) {
        Class<? extends ElasticJob> elasticJobClass = elasticJob.getClass();
        String elasticJobClassName = elasticJobClass.getName();
        return isLambdaClass(elasticJobClass) ? trimLambdaClassSuffix(elasticJobClassName) : elasticJobClassName;
    }
linghengqian commented 2 months ago

Are you going to submit a PR?