fast-reflexes
fast-reflexes

Reputation: 5196

Do annotations in Java result in compile-time transitive dependencies?

A simple example where Ent.java uses annotations and is compiled with the necessary jar dependency after which Includer.java is compiled which in turn imports Ent.java.

Ent.java:

import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name="securities")
public class Ent {}

Includer.java:

public class Includer {

    public void f() {
        Ent s = new Ent();
    }
}

Compiling this with...

javac -cp C:/apache-tomcat-7.0.59/lib/javax.persistence_2.1.0.v201304241213.jar Ent.java
javac Includer.java

...results in the following warning when compiling Includer.java:

.\Ent.class: warning: Cannot find annotation method 'name()' in type 'Table': class file for javax.persistence.Table not found

The same happens of course if we add more annotations but only annotations that take parameters seem to be causing this behaviour. Adding the jar dependency from the first compilation to the classpath when compiling Includer.java solves the problem but doesn't follow how I usually think dependencies are handled. Since I'm quite new to annotations, is it the expected behaviour that we need to add the dependencies of Ent.java to the classpath when compiling Includer.java (adding dependencies of dependencies so to speak...) or is this likely some sort of bug or some other kind of special case...? Compiler version javac 1.8.0_31 was used for this test.

Upvotes: 4

Views: 985

Answers (1)

M A
M A

Reputation: 72884

This seems related to this bug: JDK-6550655:

Compiler error when compiling a class alone that depends on another class, which has already been compiled and has a dependency on a class from persistence-api.jar

Also see related bug JDK-6365854: javac crashes when compiling against an annotated class.

To answer your question, it is not required to place dependencies of the dependency class (Ent.java) to the classpath of the depending class (Includer.java). However, it seems javac also reads the annotations in the dependency class. According to the referenced bug, this used to cause a compilation failure (a com.sun.tools.javac.code.Symbol$CompletionFailure). As mentioned in the comments, this is modified to only throw a warning:

After the fix, the compiler will accept the program but issue a warning. The rationale is that the missing annotation can cause problems when running the program.

Also from the comments:

The compiler should not crash and this problem will be addressed first.

While it is desireable to allow the compilation to continue without the annotation, I will have to investigate if it is allowable. For example, the compiler cannot determine if the missing annotation has the meta-annotation @Inherited. This can cause problems for annotation processors.

Upvotes: 2

Related Questions