tags:

views:

159

answers:

5

Hi,

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

+4  A: 

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.

mdma
+1 for Nexus and another virtual +1 for the advice to just create artifacts for the libraries (with nexus you can do it from the web frontend - so I'd recommend nexus even for a local, single-user environment)
Andreas_D
A: 

Just a thing that hit my eye: In the path you are using the normal unix-style slashes /. Windows uses backslashes for paths: . I do not know if maven is able to convert those into each other, so maybe try and enter the path as follows:

C:\gelcap\lib\zipdiff-0.4.jar

fgysin
Nops it did not make a difference
viren
+1  A: 

Try installing the jars to your local repository. That when when it's build time there shouldn't be a difference between your local jars and jars in the greater repositories.

Allain Lalonde
Hi Allain,i installed my jar file to local maven repository but when i run the target maven:install form eclipse but still it did not copy the jar to web-inf/lib folder .I did following steps:1. Run the following command mvn install:install-file -DgroupId=sourceforge.net -DartifactId=zipdiff -Dversion=0.4 -Dfile=C:/gelcap/lib/zipdiff-0.4.jar -Dpackaging=jar -DgeneratePom=trueIt created a folder for zipdiff jar file in local maven repository .Then run maven:install from eclipse. BUt still created war does not have zipdiff.jar file
viren
YOu also have to change your pom file and remove the scope of the dependency. Maven should then pull the dependency from the repository and include it in the war.
Cliff
Yup this works Thanks allain
viren
A: 

Not having tried this one before so it may not work, can you change the scope to compile?

<dependency>
   <groupId>sourceforge.net</groupId>
   <artifactId>zipdiff</artifactId>
   <version>0.4</version>
   <scope>compile</scope>
   <systemPath>C:/gelcap/lib/zipdiff-0.4.jar</systemPath>
</dependency>
Chris J
Hi Chris,FYIYou can not use system path with compile scope for
viren
cool, did not know that
Chris J
+1  A: 

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:

  • Add your libraries to your local repository via 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.
  • Install and run an "enterprise repository" like Nexus, Archiva, or Artifactory and add your libraries via deploy:deploy-file. This is the ideal scenario.
  • Setup a file based repository as described in this previous answer and put your libraries in there. This is the best compromise if you don't have a corporate repository but need to work as a team and don't want to sacrifice portability.

Please, stop using the system scope.

Pascal Thivent