Search code examples
mavengeotools

Geotools/Maven dependency order


I've been trying to track down the cause of the following Exception

org.geotools.feature.SchemaException: Error decoding srs: 4326

and I kept seeing people say that I needed the following dependency

    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-epsg-hsql</artifactId>
        <version>${geotools.version}</version>
    </dependency>

I was using the m2e eclipse plugin to build my jar and I was always able to successfully run my application through eclipse but when I would try to run my jar from the command line, I would get the exception so I knew it had to be something with the way that my jar was being built. I created a simple application with the following code to duplicate the problem.

import org.geotools.data.DataUtilities;
import org.geotools.feature.SchemaException;
import org.opengis.feature.simple.SimpleFeatureType;


public class Main {

/**
 * @param args
 * @throws SchemaException 
 */
public static void main(String[] args) throws SchemaException {

    SimpleFeatureType lineFeatureType = DataUtilities.createType("LINE", "geom:LineString:srid=4326,name:String");

    System.out.println("Success!");
}

}

my pom file looks like this

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupid</groupId>
<artifactId>artifactid</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>example</name>
<packaging>jar</packaging>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <geotools.version>12-RC1</geotools.version>
</properties>

<dependencies>
<!--        <dependency> -->
<!--            <groupId>org.geotools</groupId> -->
<!--            <artifactId>gt-shapefile</artifactId> -->
<!--            <version>${geotools.version}</version> -->
<!--        </dependency> -->
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-epsg-hsql</artifactId>
        <version>${geotools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-geometry</artifactId>
        <version>${geotools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-shapefile</artifactId>
        <version>${geotools.version}</version>
    </dependency>
</dependencies>

<repositories>
    <repository>
        <id>OSGEO GeoTools repo</id>
        <url>http://download.osgeo.org/webdav/geotools</url>
    </repository>
</repositories>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>Main</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>make-my-jar-with-dependencies</id> <!-- this is used for inheritance merges -->
                    <phase>package</phase> <!-- bind to the packaging phase -->
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
    </plugins>
</build>

What I started seeing is that if my dependencies are in this order

<dependencies>
<!--        <dependency> -->
<!--            <groupId>org.geotools</groupId> -->
<!--            <artifactId>gt-shapefile</artifactId> -->
<!--            <version>${geotools.version}</version> -->
<!--        </dependency> -->
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-epsg-hsql</artifactId>
        <version>${geotools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-geometry</artifactId>
        <version>${geotools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-shapefile</artifactId>
        <version>${geotools.version}</version>
    </dependency>
</dependencies>

Then when I execute my jar from the command line, I will see "Success!" and the exception will not occur. But if my dependencies are in this order

<dependencies>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-shapefile</artifactId>
        <version>${geotools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-epsg-hsql</artifactId>
        <version>${geotools.version}</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-geometry</artifactId>
        <version>${geotools.version}</version>
    </dependency>
<!--        <dependency> -->
<!--            <groupId>org.geotools</groupId> -->
<!--            <artifactId>gt-shapefile</artifactId> -->
<!--            <version>${geotools.version}</version> -->
<!--        </dependency> -->
</dependencies>

then the exception will occur.

I thought that the order of dependencies did not matter in a maven project. Could someone explain what is going on? I appreciate any feedback!


Solution

  • You are correct that in general mvn doesn't care about the order of dependencies, however it does work through them in the order they are presented in the pom file.

    This does become important when you are packaging jars as the default maven packager doesn't work well with the SPI files that are used by GeoTools to load factories, in this case the EPSG referencing factory.

    If you use the Maven Shade packager it will build the files correctly. There is a longer discussion and an example in the GeoTools FAQ.