1
votes

I understand that PROVIDED dependencies are "provided" by container and application don't need generate this JAR.

1) So, I'm using JBOSS EAP 7.0.0.GA and this have the following jar in this module folder: hibernate-core-5.0.9.Final-redhat-1.jar.

In my project i'm using the following dependency:

<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.0.9.Final-redhat-1</version>
        </dependency>

It works fine, without errors. But i understand that i should use "PROVIDED" scope because this jar is provided by container. Why it works ?

2) I have another example. In Jboss Eap 7.0.0.GA i have the following jar: jboss-servlet-api_3.1_spec-1.0.0.Final-redhat-1.jar. But in my project i have the following:

 <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
            <optional>true</optional>
        </dependency>

It works fine too, but i don't understand why. To me the correct dependency should be servlet-api_3.1_spec-1.0.0.Final-redhat-1 with provided. Why it works too ?

1

1 Answers

0
votes

At build time, Maven will resolve the dependencies and make the relevant packages available to the compiler. Your appserver may provide, for example, JARs that contain the classes and interfaces in javax.servlet, but these classes won't necessarily be useful to the compiler, because it doesn't know where they are. By providing the dependencies to Maven, you're having Maven find its own implementations of these dependencies, just for use at compile time.

At run time, if you've marked the dependencies as provided, then your application will use the versions provided by the appserver, rather than the versions known to Maven. This is potentially a bad thing, but it often works because the compiler really needs to know only the method signatures, not their implementations. The method signatures of classes that are controlled by specifications, such as those in javax.servlet, change only infrequently, so the mismatch between the compile-time JARs and run-time JARs may go unnoticed. Unlike OSGi-compliant JARs, JARs built for JEE do not contain meta-data that specifies particular compatible dependency versions -- JEE classloaders will use what they find, for better or worse.

You can be caught out, however -- particularly if the mismatch is substantial. Problems may be very obvious at runtime, such as exceptions related to missing classes or methods, but they can be subtle.

It's therefore often best, where practicable, to use the same compile-time versions of dependencies as the versions that will be available at runtime. For EAP, I recall that Red Hat distributes a Maven bill-of-materials (BOM) file that specifies all the versions of all the EAP JARs for specific EAP releases.