I am trying to build my application using maven and eclipse. I have dependencies on 3rd party jars which are on my local machine. here is my pom.xml
<dependency>
<groupId>sourceforge.net</groupId>
<artifactId>zipdiff</artifactId>
<version>0.4</version>
<scope>system</scope>
<systemPath>C:/gelcap/lib/zipdiff-0.4.jar</systemPath>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.11</version>
</dependency>
when i run mvn : install it creates war file for my project. But problem is it does not include zipdiff.jar file to the web-inf/lib folder it only includes the files which are downloaded. I need to include copy the files from my local system also but maven ignores them. I have not got any thought why it is happening why maven is not including files with system scope to my war file. Please give me any idea how this problem can be resolved. Thanks in advance
With "system" scope, the container is expected to provide the artefact. From the maven docs:
provided
This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.
[...]
system
This scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository.
By using a system scope, you are indicating to the war plugin that the container will provide this dependency. Since this is not what you are intending to do, the simplest solution is to put the artefact in a repository, either your local maven repository, or your own maven repo on your intranet, if you have one.
The install:install-file goal can be used to install a single file (without POM) to your local repository. After doing this, change the dependency type to "compile" and remove the "systemPath" element.
In my day job, we use Nexus to manage a company-wide repository on our intranet. You can have separate repositories for your own artefacts, vs third party artefacts. Nexus also acts as a proxy, caching artefacts from external repositories, speeding up the build quite a bit. This means that only the developer that uses a new dependency that is not available in the other repos has to upload - after that, all the other devs can use it - they can checkout from SCM and build without worrying about where the dependencies are located.
I have not got any thought why it is happening why maven is not including files with system scope to my war file. Please give me any idea how this problem can be resolved.
This is by design, system
scoped dependencies are supposed to be provided as documented.
Actually, I've written numerous times (here, here, here and here) that system
scoped dependencies should be avoided. They are most of time a bad practice, people are abusing them, and they generate almost always more troubles than benefits.
Let me quote the Dependency Scopes mini guide if you want an "official" point of view:
system
: This dependency is required in some phase of your project's lifecycle, but is system-specific. Use of this scope is discouraged: This is considered an "advanced" kind of feature and should only be used when you truly understand all the ramifications of its use, which can be extremely hard if not actually impossible to quantify. This scope by definition renders your build non-portable. It may be necessary in certain edge cases. The system scope includes the<systemPath>
element which points to the physical location of this dependency on the local machine. It is thus used to refer to some artifact expected to be present on the given local machine an not in a repository; and whose path may vary machine-to-machine. The systemPath element can refer to environment variables in its path:${JAVA_HOME}
for instance.
So, instead of using the system
scope, either:
install:install-file
. This is a quick and dirty way to get things working, it might be an option if you're alone but it makes your build non portable. deploy:deploy-file
. This is the ideal scenario.Please, stop using the system
scope.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With