Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Maven "compiler-only" scope for dependency artifacts

Tags:

I realise this is more of a semantic quest rather than a functionality quest.

I have three types of compile-scope dependencies:

  1. Compile-only scope, not used at run-time. GWT client-side dev, MVP4G, RestyGWT, Source retention annotation processors. I use REST, so I don't need GWT server side.

  2. Provided - Hibernate jars required for compilation but provided by JBoss.

  3. Compile + runtime jars.

For case 2, we could use provided scope. Case 3, we would use compile scope.

However for case 1, I use provided scope, even though JBoss does not provide those files at all. Nor are they needed at run-time.

Anyway, don't you think Maven should provide for a synonym for "provided" for a scope where the artefacts are not really needed except at compile time? Perhaps, should there be a "compile-only" scope?

like image 959
Blessed Geek Avatar asked Oct 10 '12 16:10

Blessed Geek


People also ask

What are the dependency scopes in Maven except?

There are two types of dependencies in Maven: direct and transitive. Direct dependencies are the ones that we explicitly include in the project. On the other hand, transitive dependencies are required by direct dependencies. Maven automatically includes required transitive dependencies in our project.

What is the difference between compile and provided scope in Maven?

provided scope is only available on the compilation and test classpath, whereas compile scope is available in all classpaths. provided dependencies are not packaged.

Which scope is default scope in Maven?

compile This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.

Are Maven dependencies compiled?

Maven includes a dependency with this scope in the runtime and test classpaths, but not the compile classpath.


2 Answers

Don't complain that the language does not offer fine distinctions if you only know half its vocabulary.

If a dependency is only used for building, such as an annotation processor, it should be a maven <plugin>, or <dependency> thereof.

Otherwise, if it is in the compilation classpath, it will be necessary for linking the generated class file at runtime. Then, there are two cases:

  1. It is always necessary to load that class
    1. the class should be shipped as part of the application: <scope>compile</scope>
    2. the class should be provided by the runtime environment: <scope>provided</scope>
  2. It is sometimes necessary (because that class will be loaded only under particular circumstances): <optional>true</optional>

The only option not covered is compiling a Java program, and never running it in a JVM. This is a really obscure use case, and I can't fault the designers of maven for not including a scope just to express this distinction - particularly since it is irrelevant to Maven's core responsibility (building the software).

like image 156
meriton Avatar answered Sep 17 '22 12:09

meriton


If the jars with are not true "runtime" dependencies (only for building) but not for the final artifact, you can exclude them various means:

  1. Exclusion in the assembly descriptor
  2. Exclusion in the jar (or war, ear, whatever) plugin configuration
  3. Shade Plugin minimize jar goal

I agree that shipping unnecessary classes is annoying (I've seen junit and testng jars in production deployments - brrrr...), but for all practical purposes it's a rather minor one.

If you have a dependency conflict (i.e shipping a "all deps" version of a library or framework), that's a different story, but doesn't sound like what you're facing here.

like image 40
noahlz Avatar answered Sep 18 '22 12:09

noahlz