Closed
Description
If spring-context-indexer
is used in an application that uses @javax.transaction.Transactional
(which is provided by spring-boot-starter-data-jpa
), compilation will fail due to javax.interceptor.InterceptorBinding
not being available.
This can be easily reproduced with a project as simple as:
plugins {
id 'java'
id 'io.spring.dependency-management' version '1.0.6.RELEASE'
id 'org.springframework.boot' version '2.1.2.RELEASE'
}
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2'
annotationProcessor 'org.springframework:spring-context-indexer'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
@SpringBootApplication
@javax.transaction.Transactional
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
$ ./gradlew compileJava
> Task :compileJava FAILED
error: cannot access InterceptorBinding
class file for javax.interceptor.InterceptorBinding not found
Consult the following stack trace for details.
com.sun.tools.javac.code.Symbol$CompletionFailure: class file for javax.interceptor.InterceptorBinding not found
1 error
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileJava'.
> Compilation failed; see the compiler error output for details.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 0s
1 actionable task: 1 executed
Adding the following dependency addresses the problem:
implementation 'javax.interceptor:javax.interceptor-api:1.2.2'
Since spring-boot-starter-data-jpa
pulls in javax.transaction-api
I believe it should also provide javax.interceptor-api
having in mind the definition of javax.transaction.Transactional
:
@Inherited
@InterceptorBinding // <= comes from javax.interceptor-api
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Transactional {