Maven’s configuration file path reading

Time:2021-1-12

When using XML configuration to build the core class sqlsessionfactory of mybatis, we encountered the problem that the configuration file path is always written incorrectly. After the event, I didn’t look at the documents well, and I was always feeling the elephant for the blind.

The code to read the XML configuration file is as follows:

var inputSteam = Resources.getResourceAsStream("config/mybatis.xml");
var sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputSteam);

At first, I put the configuration file in thesrc/main/java/com/imxfly/config/mybatis.xmlThen the read path is written as:com/imxfly/config/mybatis.xmlBut the hintjava.io.IOException: Could not find resource com/imxfly/config/mybatis.xml

So the key is how to fill in the configuration file path here. We know that the read path is not according to the directory structure at the time of current development, but is read after compilation in the target directory of the project with the classes directory as the classpath (that is, the root directory of the class).

Suppose we put the configuration file in thesrc/main/java/com/imxfly/configDirectory, then usemaven compileAfter compiling, go to the target directory and you will find that you can’t find this configuration file. This is because Maven only reads it by default when compilingsrc/main/javaUnder the directory.javaThe file is then compiled into.classFile, so you can’t find our configuration file in the target directory. How can we solve this problem?

The recommended approach is to put these XML configuration files in thesrc/main/resourcesUnder the directory.

This behavior is clearly described in the official document (click to view)

Within artifact producing source directories (ie. main and test), there is one directory for the language java (under which the normal package hierarchy exists), and one for resources (the structure which is copied to the target classpath given the default resource definition).

For the resources directory, its directory structure will be completely copied directly to the target classpath. Suppose we have the following SRC directory structure:

.
├── main
│   ├── java
│   │   └── com
│   │       └── imxfly
│   │           └── App.java
│   └── resources
│       └── config
│           └── mybatis.xml
└── test
    └── java
        └── com
            └── imxfly
                └── AppTest.java

Then the target directory structure after compilation is as follows:

.
├── classes
    ├── com
    │   └── imxfly
    │       └── App.class
    └── config
        └── mybatis.xml

So the path to read the configuration file in the code is as follows:

var inputSteam = Resources.getResourceAsStream("config/mybatis.xml");

Because by default, Maven willsrc/main/resourcesFind the resource file for the project.

But if our project structure is not easy to modify, the configuration file is in thesrc/main/java/com/imxfly/config/mybatis.xmlWhat to do?

At this point, we need to configure the file in Maven pom.xml To tell Maven where our resource files are:

<project>
 ...
 <build>
   ...
   <resources>
     <resource>
       <directory>src/main/java/com/imxfly/config</directory>
     </resource>
     <resource>
       <directory>src/main/java/com/imxfly/config2</directory>
     </resource>
     <resource>
       <directory>src/main/java/com/imxfly/config3</directory>
     </resource>
   </resources>
   ...
 </build>
 ...
</project>

At compile time, Maven will completely copy the file structures in these directories to the target directory (just like copying the resources directory above), so our reading path is:

var inputSteam = Resources.getResourceAsStream("mybatis.xml");

reference material:

  • https://maven.apache.org/plugins/maven-resources-plugin/examples/resource-directory.html
  • https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html