1

I am trying to figure out the exact effects in regards to compile time and runtime classpaths of a class annotated with a runtime level retention annotation, for example: @javax.inject.Named. This is my understanding so far:

  1. The javax.inject.Named class must be present at compile time on the classpath.
  2. This is then compiled into the bytecode as meta-data and can be obtained at runtime via the Reflections API and processed accordingly; however, this class DOES NOT need to exist on the runtime classpath.

Thus, if I compile a jar with a java class annotated with @javax.inject.Named, this compiled jar file can be run both in a container (ie Jboss) and in a plain old JVM launched from the command line (with no additional classpath entires). However, if I make this source code available to a project that will be compiled along with it just using javac (and no additional classpath entires), it will no longer compile correctly? If this assumption is correct, this seems to be a little limiting if I need to share both compiled binaries and source files amongst projects that may or may not be running in a container (ie Jboss).

If this is the case, would I need to create a wrapper object (annotated with @javax.inject.Named) that delegates to the inner, non-annotated object? Is another option to disable annotation processing at compile time? See http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html#processing

GreenieMeanie
  • 3,560
  • 4
  • 34
  • 39

1 Answers1

0

You need the annotation to be present in the compile classpath to compile source files using the annotation. You don't need it in the classpath to compile a class A using a compiled class B using the annotation.

Many open-source libraries (like Guava or DbSetup for example) use the javax.annotation or Findbugs annotations for example, but you don't need to have those annotations in the classpath to compile (and run) your own source code relying on these libraries.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • The difference being that javax.annoation is in rt.jar and thus will always be available to either the compiler or runtime classpath, while my specific annotation above (javax.named.Inject), is not in rt.jar and isn't part of the standard JDK as far as I know. – GreenieMeanie Apr 01 '15 at 17:31
  • By javax.annotation, I mean the annotations like Nonnull, Nullable, etc., which are part of JSR305 and are not in the JDK. FindBugs annotations are not in the JDK either – JB Nizet Apr 01 '15 at 17:41
  • So by "No, you need...", you really mean "Yes, you need...", ie you must always have the annotations in the compile time classpath when directly compiling that file? Does it matter if you used an import of the package vs a fully qualified annotation name, ie import @ javax.inject.Named; Named class A {.. } vs using @ javax.inject.Named class A{ ... } – GreenieMeanie Apr 01 '15 at 17:48
  • @GreenieMeanie the "No" was a reaction to your incorrect assumption in the question. I removed it as it was indeed confusing. Whether you use the fully qualified name or an import doesn't change anything: if a source file uses a class, the compiler checks this class exists and is used correctly in the source file (i.e. the annotation is used where it's supposed to be used, has the required attributes, etc.) – JB Nizet Apr 01 '15 at 18:15
  • Okay, so when the compiled jar with that annotation is LINKED, whether that linkage is at runtime or compile time, that annotation need not be present on either path. However, when compiling that class with the annotation directly, the compiler obviously needs that class. So with this in mind, and considering for my requirements that this class WOULD sometimes be re-compiled directly and not linked, is my suggested solution of the wrapper class viable? Thanks! – GreenieMeanie Apr 01 '15 at 18:25
  • I don't see why you would provide a library as source code only, and I don't see why, if you do it, the using project would not include the library containing the annotations in the classpath. Why find a complex solution when the simple, obvious one, works fine? – JB Nizet Apr 01 '15 at 18:28
  • That is irrelevant to the question and isn't under my control. It's not as source code only - sometimes it's used as a pre-built binary and sometimes it is re-compiled and re-distributed as part of another binary. – GreenieMeanie Apr 01 '15 at 18:32
  • Again, if a project decides to compile source code, it must be prepared to depend on the libraries used by that source code. I would never duplicate and wrap every object, leading to horrible design, just to satisfy such a strange requirement of wanting to compile source code but refusing to depend on its compile dependencies. – JB Nizet Apr 01 '15 at 18:40