10

I need to generate module.xml file for JBoss7 for a maven project which has a lot of jar-dependencies. What is the easiest way to do it? The file looks like:

<module xmlns="urn:jboss:module:1.0" name="ats.platform">
  <resources>
    <resource-root path="dom4j-1.6.1.jar"/>
    <resource-root path="jdom-1.0.jar"/>
...
  </resources>
</module>

so that the <resource-root> element should be created for each project jar-dependency.

Or maybe I doing something wrong? What's correct way to create a JBoss7 module from a maven project?

Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277
kan
  • 28,279
  • 7
  • 71
  • 101
  • I had done a program that will remove unwanted(unused) jars from a project class path. Are u looking for such a thing? – Naveen Babu Oct 16 '11 at 07:15
  • No, I need to build a jboss-module from an existing maven project. But interesting, what do you mean "remove" and "unwanted"? As I understand you could just manage `` in pom file. What does exactly the program do? – kan Oct 16 '11 at 10:56
  • Usually we used to add all ur jars and then eliminate one by one and check the dependencies. But instead i created a program which will read all jars u have initially mapped. Then i will find the ones that doesn't have dependency to current project or any related classes in the current project. And i give the output of the wanted jars and unwanted jars and the one jars that are needed for your project to work. – Naveen Babu Oct 16 '11 at 13:33
  • Usually I'll keep dependencies up-to-date, so all that listed is required. Moreover, some dependencies could be implicit, e.g. an API implementation (xerces or ws) or jdbc-drivers. – kan Oct 16 '11 at 15:19

4 Answers4

4

You could try smartics-jboss-modules-maven-plugin

It provides quite powerful dependency control:

  • exclusions and inclusions (also with wildcards) of project deps,
  • definition of deps to other JBoss modules,
  • transitive dependencies handling
  • and lot more

With proper descriptor, generated module is ready to be copied 'as is' to JBoss 7.

Example jboss-modules/foo.bar.foo-module.xml:

<modules xmlns="http://smartics.de/ns/jboss-modules-descriptor/1">
<module name="foo.bar.foo-module">
    <match>
        <includes>
            <include>
                <groupId>foo.*</groupId>
            </include>
            <include>
                <groupId>org.*</groupId>
            </include>
        </includes>
        <excludes>
            <exclude>org.slf4j.slf4j-api</exclude>
        </excludes>
    </match>

    <apply-to-module>
        <dependencies>
            <module name="org.slf4j" />
        </dependencies>
    </apply-to-module>
</module>

Also set excludeDependencyManagementDependenciesInPomProject to true in smartic plugin configuration to avoid including 50 MB of deps :)

rfoltyns
  • 389
  • 3
  • 10
4

I don't really know about JBoss and whether there's another way to do this, but you can do it quite simply with GMaven:

<plugin>
    <groupId>org.codehaus.gmaven</groupId>
    <artifactId>gmaven-plugin</artifactId>
    <version>1.3</version>
    <configuration>
        <source>
            def sw = new StringWriter()
            def xml = new groovy.xml.MarkupBuilder(sw)
            xml.module(xmlns:'urn:jboss:module:1.0', name:'ats.platform') {
              resources {
                project.runtimeClasspathElements.each {
                  def path = it.find(".*?([\\w\\.-]*\\.jar)") { it[1] }
                  !path?:'resource-root'(path:path)
                }
              }
            }
            println sw
        </source>
    </configuration>
</plugin>

A couple of things to note:

  1. That script spits the XML out to stdout, but you can obviously write it to a file or whatever very easily.
  2. The runtimeClasspathElements contain absolute paths to the jar, which is why I parse it with a regex. You can adjust the regex to include more of the path or just prepend a string if you need more than just the jar file name.

I've posted a working example on github (it's just a POM) where I've bound the above plugin configuration to the initialize build phase. If you have git, you can clone and run it yourself with:

git clone git://github.com/zzantozz/testbed tmp
cd tmp
mvn -q initialize -pl stackoverflow/7755255-gmaven-to-build-xml-from-classpath

In the sample project, I added jdom 1.0 and dom4j 1.6.1 as dependencies, and here's the output it created:

<module xmlns='urn:jboss:module:1.0' name='ats.platform'>
  <resources>
    <resource-root path='jdom-1.0.jar' />
    <resource-root path='dom4j-1.6.1.jar' />
    <resource-root path='xml-apis-1.0.b2.jar' />
    <resource-root path='aspectjrt-1.6.11.jar' />
  </resources>
</module>

Note: I'm not a groovy expert, so there may be a groovier way to do it, but you can see how easy it is even so.

Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
  • 1
    Where can I find a documentation for gmaven? Google shows some stale links... E.g. where is a description of things such "runtimeClasspathElements"? – kan Oct 16 '11 at 20:22
  • The Google links aren't stale. Read the page and follow the links. GMaven has a [wiki at Codehaus](http://docs.codehaus.org/display/GMAVEN/Home) with a lot of the essentials in it. The documentation *is* a little light, unfortunately, but with Groovy, it's usually pretty easy to find your way around. – Ryan Stewart Oct 16 '11 at 21:43
  • I cannot find any information for the stuff. E.g. `runtimeClasspathElements` is not described here. Or I am looking in wrong direction? http://docs.codehaus.org/dosearchsite.action?queryString=runtimeClasspathElements gives nothing. I have no doubt it's should be more proper way to extract filenames and artifact packaging types instead of using the regexp magic. Also it's not clear which scope of dependencies they are - compile, runtime, test, etc. – kan Oct 17 '11 at 08:34
  • Yes, wrong direction. `project` is [the MavenProject](http://maven.apache.org/ref/3.0.3/maven-core/apidocs/org/apache/maven/project/MavenProject.html#getRuntimeClasspathElements%28%29)--part of the Maven API and nothing to do with GMaven. Everything you need to know about Maven is on [its project page](http://maven.apache.org/ref/3.0.3/). Javadoc is in the typical place for Maven projects. There's also [a blog post that mentions it](http://agileice.blogspot.com/2009/04/accessing-maven-runtime-classpath-in.html). Besides, I thought **runtime**ClasspathElements was very explicit about its scope. – Ryan Stewart Oct 17 '11 at 13:01
  • Oh, and you can always introspect at runtime: `project.getMetaPropertyValues().each { println it.name + ": " + it.value }`, using the [Groovy Object extension](http://groovy.codehaus.org/groovy-jdk/java/lang/Object.html#getMetaPropertyValues%28%29). More on it in [this blog](http://noor.ojuba.org/2008/07/groovy-introspection-know-what-you-have/), the [groovy.inspect package](http://groovy.codehaus.org/api/groovy/inspect/package-summary.html), and in [Groovy Reflection](http://groovy.codehaus.org/JN3535-Reflection). – Ryan Stewart Oct 17 '11 at 13:12
2

This can be easily solved in a few steps.

  1. run mvn dependency:list -DoutputFile=dep.list -DoutputAbsoluteArtifactFilename=true in your shell

    you will receive a file like this:

    The following files have been resolved:
        ch.qos.logback:logback-classic:jar:0.9.30:test:C:\Dokumente und Einstellungen\michael-o.m2\repository\ch\qos\logback\logback-classic\0.9.30\logback-classic-0.9.30.jar
        ch.qos.logback:logback-core:jar:0.9.30:test:C:\Dokumente und Einstellungen\michael-o.m2\repository\ch\qos\logback\logback-core\0.9.30\logback-core-0.9.30.jar
        classworlds:classworlds:jar:1.1-alpha-2:compile:C:\Dokumente und Einstellungen\michael-o.m2\repository\classworlds\classworlds\1.1-alpha-2\classworlds-1.1-alpha-2.jar
    

    The important information is indented by 4 spaces in the file.

  2. Now grep out the important information and do not forget to limit to compile and runtime scope.

  3. split columns with cut -d ':' -f <colNum> and get the last column.
  4. Get the filename after the last (back)slash.
  5. Now build an XML file with the information.

Every can be packed in a nice shell script.

See the maven-dependency-plugin for reference.

A quick command looks like this: cat dep.list | grep -E ':(compile|runtime):' | cut -d ':' -f 7 | sed -e 's/\///g' | xargs -I {} basename '{}' | xargs -I {} echo "<resource-root path=\"{}\" />"

The output contains the jar files names:

<resource-root path="classworlds-1.1-alpha-2.jar" />
<resource-root path="jsr305-1.3.9.jar" />
<resource-root path="guava-10.0.1.jar" />
<resource-root path="commons-codec-1.3.jar" />
<resource-root path="commons-io-2.0.1.jar" />
<resource-root path="commons-lang-2.6.jar" />
<resource-root path="junit-4.9.jar" />

Now wrap with XML header and footer, and you are done!

Michael-O
  • 18,123
  • 6
  • 55
  • 121
  • It's platform dependent. Windows doesn't have grep, sed, etc. I think it should be possible using maven-antrun-plugin, but don't know it very well (I expect that the standard ant is not powerful enough for the task). As a last resort - I could make a new maven plugin for it. – kan Oct 16 '11 at 18:06
  • 1
    Yes, it is. Surely it could be done with antrun but way more work than my single unix cmd line. Obviously you can't avoid coding. – Michael-O Oct 16 '11 at 18:13
1

Although this question is quite old and already has a valid answer, I'd like to mention another alternative.

As we started with JBoss modules we wrote a small plugin for Maven that generates module folders with module.xmls based on XML descriptors. The plugin is called smartics-jboss-modules-maven-plugin and you'll find additional information about it at the project's blog.

We just started to work with it, but it already makes the process of synchronization between the POM and the module.xml (plus directory structure) for our projects very easy.

The downside of this approach is that you have to learn an additional XML descriptor and have to configure an additional Maven plugin. So for small projects you may be better off following the solutions of the answers above.

If you want to give it a try, the plugin is licensed under Apache License 2.0.

Robert Reiner
  • 531
  • 3
  • 9