title: Spring Batch @StepScope cannot generate CGLIB subclass
body: <p><strong>EDIT</strong></p>
  
  <p>I created a test project that replicates the issue. It can be found at <a href="https://github.com/tomverelst/test-batch" rel="nofollow">https://github.com/tomverelst/test-batch</a>.</p>
  
  <p>First run the maven command <code>exec:java</code> to start a HSQL database. Then you can run the JUnit test <code>MigrationJobConfigurationTest</code> to load the Spring application context.</p>
  
  <p><strong>Original question</strong></p>
  
  <p>When starting my Spring Batch application, I get the following exception when Spring is loading my job's configuration:</p>
  
  <pre><code>Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy34]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy34
  </code></pre>
  
  <p>This is caused by the <code>@StepScope</code> annotation in my job's configuration. It attempts to proxy a class with CGLIB which is already proxied with a JDK proxy and I don't know where this JDK proxy is coming from.</p>
  
  <p>I have also tried using <code>@Scope(value = "step", proxyMode = ScopedProxyMode.NO)</code>, but then I get a stack overflow error when invoking the JDK proxy, which keeps invoking itself.</p>
  
  <p>The application starts correctly if I remove the <code>@StepScope</code> annotations, but I need to be able to use them for my jobs.</p>
  
  <p><strong>Spring config</strong></p>
  
  <pre><code>&lt;context:component-scan base-package="com.jnj.rn2.batch" /&gt;
  
  &lt;context:annotation-config /&gt;
  
  &lt;aop:aspectj-autoproxy proxy-target-class="true" /&gt;
  
  &lt;bean class="org.springframework.batch.core.scope.StepScope" /&gt;
  
  // Job repository etc
  ...
  </code></pre>
  
  <p><strong>MigrationJobConfiguration</strong></p>
  
  <pre><code>@Configuration
  public class MigrationJobConfiguration {
  
      @Autowired
      private JobBuilderFactory jobs;
  
      @Autowired
      private StepBuilderFactory steps;
  
      @Autowired
      private MigrationService migrationService;
  
      @Bean
      public Job migrationJob() {
          return jobs.get( "migrationJob" )
              .start( migrateCrfStep() )
              .next( indexRequestsStep() )
              .build();
      }
  
      @Bean
      public Step migrateCrfStep() {
          return steps.get( "migrateCrfStep" )
              .tasklet( migrateCrfTasklet() )
              .build();
      }
  
      @Bean
      public Step indexRequestsStep() {
          return steps.get( "indexRequestsStep" )
              .&lt;LegacyRequest,LegacyRequest&gt; chunk( 5 )
              .reader( indexRequestReader() )
              .processor( indexRequestProcessor() )
              .writer( indexRequestWriter() )
              .build();
      }
  
      @Bean
      @StepScope
      public MigrateCrfTasklet migrateCrfTasklet() {
          return new MigrateCrfTasklet();
      }
  
      @Bean
      @StepScope
      public IndexRequestItemReader indexRequestReader() {
          return new IndexRequestItemReader();
      }
  
      @Bean
      @StepScope
      public IndexRequestItemProcessor indexRequestProcessor() {
          return new IndexRequestItemProcessor();
      }
  
      @Bean
      @StepScope
      public IndexRequestItemWriter indexRequestWriter() {
          return new IndexRequestItemWriter();
      }
  
      // Setters
      ...
  }
  </code></pre>