views:

241

answers:

1

I'm trying to write a pom.xml that will allow me to run a command locally and fetch all dependencies that my jruby Rails app has. I'm seeing two different configs though and I'm not totally sure which to use (as I'm not a java person whatsoever)

First, many Pom's i'm seeing just have a tag under the root of the pom.xml that list all dependencies. This doesn't however have any information about where these are stored etc... so I feel like this isn't what I want (I need to copy them to my rails lib dir)

Second option, I'm seeing in the mvn docs is to use the maven-dependency-plugin, which seems more like what i'm looking for. I assume then that my outputDirectory would be something like lib

So I don't fully understand what the purpose of the first option's dependency list is for. All I want is mvn to copy my jars locally (and then eventually when my CI server does a deploy). Can someone point me in the right direction?

First Option

<project>
  <dependencies> 
   <dependency>
     <groupId>commons-lang</groupId>
     <artifactId>commons-lang</artifactId>
     <version>2.4</version>
   </dependency>
</project>

Second Option

<project>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <configuration>
          <artifactItems>
            <artifactItem>
              <groupId>[ groupId ]</groupId>
              <artifactId>[ artifactId ]</artifactId>
              <version>[ version ]</version>
              <type>[ packaging ]</type>
              <classifier> [classifier - optional] </classifier>
              <overWrite>[ true or false ]</overWrite>
              <outputDirectory>[ output directory ]</outputDirectory>
              <destFileName>[ filename ]</destFileName>
            </artifactItem>
          </artifactItems>
          <!-- other configurations here -->
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
A: 

First, many Pom's i'm seeing just have a tag under the root of the pom.xml that list all dependencies. This doesn't however have any information about where these are stored etc... so I feel like this isn't what I want (I need to copy them to my rails lib dir)

This is the traditional way to declare and use dependencies on a Java project. Dependencies declared under the <dependencies> element are downloaded from a "remote repository" and installed to your "local repository" (in ~/.m2/repository by default) and artifacts are then handled from there. Maven projects (at least the Java ones) don't use a local lib/ folder for their dependencies.

Second option, I'm seeing in the mvn docs is to use the maven-dependency-plugin, which seems more like what i'm looking for. I assume then that my outputDirectory would be something like lib

The maven dependency plugin allows to interact with artifacts and to copy/unpack them from the local or remote repositories to a specified location. So it can be used to get some dependencies and copy them in lets say a lib/ directory indeed. Actually, it has several goals allowing to do this:

  • dependency:copy takes a list of artifacts defined in the plugin configuration section and copies them to a specified location, renaming them or stripping the version if desired. This goal can resolve the artifacts from remote repositories if they don't exist in local.
  • dependency:copy-dependencies takes the list of project direct dependencies and optionally transitive dependencies and copies them to a specified location, stripping the version if desired. This goal can also be run from the command line.

The first goal would use the setup you described in your second option. The second goal would use the standard project dependencies that you described in your first option. Both approaches would work.

The problem here is that I don't know exactly what a JRuby Rails app is, what the development workflow is, how to build such an app, etc so I don't know exactly what you need to do and, consequently, what would be the best way to implement that with Maven.

So I googled a bit and found this post that shows another approach based on OS commands (using the maven exec plugin) and has a complete pom.xml doing some other things. Maybe you should look at it and use it as a starting point instead of reinventing everything. This is my suggestion actually.

Pascal Thivent
wow thanks for the link, I searched for over an hour to find something like that. Also, thx for the info. If I understand correctly then: If I define my dependencies at the root of the project in the pom in the <dependencies> tag, I don't use the maven-dependency-plugin and I (somewhere) describe in my pom where to copy them. If I don't define my dependencies in that root dependencies tag, but rather in the maven-dependency-plugin, I specify each dependency as an artifact including where I want it copied to??
brad
hmmm... unfortunately that's more of a pom for deploying an app, where they're setting up a war, file and copying the files to that war. Not exactly what I want, but I'm pretty sure I understand what I need.
brad
@brad You're welcome. Now, regarding your question: not exactly. In both both case, you would use the maven-dependency-plugin but it has *several* goals (ways to invoke it if you prefer) and you would just use different goals. As documented, `dependency:copy` takes a list of artifacts defined in the plugin configuration section. On the other hand, `dependency:copy-dependencies` takes the list of project direct dependencies (...). I didn't provide the configuration snippet because I thought this wouldn't be relevant. If you really want to see how this could be done, let me know.
Pascal Thivent
@brad At the end, don't you need a war?
Pascal Thivent
no i think that's sufficient. Yes in the end I do want a War file, but I'm going to leave that to my CI server Hudson. So, at some point I will need to write my pom to allow Hudson achieve that, but for the time being I'm going to use Maven for dependency management only and use my current Capistrano/Warbler (it's a rails thing) setup for actually creating the War and deploying. Thanks again
brad
ok I was able to get dependencies copied using the dependency:copy-dependencies goal. It didn't seem to matter though if I declared the maven-dependency-plugin. I put my dependencies in that root <dependency> tag, and used the config found here:http://maven.apache.org/plugins/maven-dependency-plugin/usage.html for copy-dependencies. But it always goes to target/dependencies. I could only put the jars where I wanted by specifying on the command line mvn dependency:copy-dependencies -DoutputDirectory=lib/jars. Not ideal. I'd rather have that in the config. Thoughts?
brad
*It didn't seem to matter though if I declared the maven-dependency-plugin* It will be found by default (because this is a plugin from `org.apache.maven.plugins`) but it will use default values for the configuration parameters then. *But it always goes to target/dependencies.* That's the default for `outputDirectory`. *I could only put the jars where I wanted by specifying -DoutputDirectory=lib/jars*. Indeed. The other way would be to put this parameter in the pom, in the `<configuration>` of the plugin (often preferred).
Pascal Thivent
Ya I did that and it wasn't working, but then I red that in order to run this on command line, the configurations shouldn't be in an executions tag (I assume that's use for mvn's automated packaging or something). Removing that worked like a charm!! Thanks again.
brad