Teach you to play maven scaffold hand in hand

Generate scaffolding

With the continuous stability of the new framework (which also brings good benefits), new projects and reconstruction projects continue to cut to the new framework. For this reason, the new framework should be a scaffold.

The demo is included in the scaffold (the framework is for learning, and there will be some convenient adjustments in the actual development)

matters needing attention

  • Mvava must be configured depending on maven environment_ HOME

  • Rely on jdk environment (jdk must be used, not jre)

  • The template of Maven archetype uses velocity

Import plug-ins and custom configuration files

First find a demo that can run, and introduce maven plugin of scaffold into pom file. My project structure is as follows:  

Project address: https://github.com/yxkong/ddd-framework/tree/main/ddd-demo

demo written based on ddd application framework

  • adapter layer

  • application layer

  • Domain domain layer

  • infrastructure Infrastructure Layer

Our project structure

Import in the pom file of demo

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-archetype-plugin</artifactId>
    </plugin>


The workflow of Maven archetype plugin is as follows:    See here for details:   http://maven.apache.org/archetype/maven-archetype-plugin/

Customize archetype.properties

package=com.yxkong.demo
version=1.0
groupId=com.yxkong
artifactId=ddd-demo
# Files that need to be ignored will not be packaged
excludePatterns=/**/*.iml,/.idea/**/*,/logs,/target
# You need to use template to resolve and replace the parameters defined in this configuration file
archetype.filteredExtensions=java,sql,yml,xml,properties,factories,ftl
# User defined parameters can be used in the template
appName=demo
upperAppName=Demo
webPort=8081
author=yxkong


Command generation scaffolding

In the DDD demo project, execute the following command

Specify setting (I use two sets of configuration locally, so I specify it through - s)

mvn clean archetype:create-from-project -Darchetype.properties=archetype.properties  -s /Users/yxk/javaServer/maven/apache-maven-3.6.3/conf/settings-aliyun.xml


Specify archetype.properties

mvn clean archetype:create-from-project -Darchetype.properties=archetype.properties

If there are no user-defined parameters, you can directly execute the following commands, all of which use the default mvn

mvn archetype:create-from-project

After executing the command, the generated sources directory resource will be generated in the target directory

Scaffold formwork treatment

Create an empty project DDD archetype and copy the generated sources in the target directory

Basic framework modification

Modify the groupId, artifactId and version of the framework you want to define. The archetype * related parameters referenced when generating code come from here.

ddd-archetype/pom.xml

  <groupId>com.yxkong</groupId>
  <artifactId>ddd-archetype</artifactId>
  <version>0.1</version>
  <packaging>maven-archetype</packaging>

  <name>ddd-archetype</name>

custom.properties

#set( $appName = ${package} )
#if(${package.indexOf(".")}!=-1)
    #set( $cc = ${package.split(".")})
    #if($cc != $null && ${cc.size()} > 0)
        #set( $lastIndex = $cc.size() - 1 )
        #set( $$appName = $cc[$lastIndex] )
    #end
#end
#set( $upperAppName = ${appName}.substring(0).toUpperCase() )

Personalized modification

To personalize modification, we must know some basic rules:

Pass in file ${Variable name} To replace
 Pass in path__Variable name__ To replace
 The existing variables are as follows:
- 
- appName  Application name initial lowercase mvn archetype:generate injection
- upperAppName The first character of the application name is capitalized mvn archetype:generate injection
- webPort Application startup port through mvn archetype:generate injection
- author  author  adopt mvn archetype:generate injection
- dbName  Database name passed mvn archetype:generate injection
- package To generate an enrollment, click mvn archetype:generate injection
- groupId To generate groupId adopt mvn archetype:generate injection
- artifactId To generate artifactId (The in each module is different and depends on mavne (structure of)
- version The version number to be generated is passed mvn archetype:generate injection
- rootArtifactId  parent Medium artifactId
- rootGroupId parent Medium artifactId The general situation is the same

Here I some requirements. Every time I generate a demo, I need to add a module prefix. For example, when I generate a user DDD project, the internal structure needs to be as follows:

user-ddd
 - user-adapter
   - com.yxkong
      -  UserStater.java
   - com.yxkong.user.adapter
 - user-application
   - com.yxkong.user.application
 - user-domain
   - com.yxkong.user.domain
 - user-infrastructure
   - com.yxkong.user.infrastructure

Modified place:

  • The module name is preceded by__ appName__- Module name

  • All in the module   package. Module name

  • All references in the class are replaced with package

The point here is src/main/resources/META-INF/maven/archetype-metadata.xml

  <modules>
    # Note that dir must be the same as the real directory in the project (variables will not be parsed). When generating, it will go to the copy template in the corresponding directory, and then generate a new project
    # Both id and name are the name of the module to be generated
    <module id="${appName}-adapter" dir="__appName__-adapter" name="${appName}-adapter">

 </modules>

Generate archetype catalog and upload

After the adjustment of all places, it shall be implemented in the project

mvn clean install

archetype-catalog.xml will be produced in the local warehouse, and the content is defined in DDD archetype / pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<archetype-catalog xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-catalog/1.0.0 http://maven.apache.org/xsd/archetype-catalog-1.0.0.xsd"
    xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-catalog/1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <archetypes>
    <archetype>
      <groupId>com.yxkong</groupId>
      <artifactId>ddd-archetype</artifactId>
      <version>0.1</version>
      <description>Parent pom providing dependency and plugin management for applications built with Maven</description>
    </archetype>
  </archetypes>
</archetype-catalog>


Upload remote server

mvn deploy

Generate project from scaffolding

Find an empty directory and execute the following commands. Remember, remember, remember

mvn archetype:generate  -DarchetypeGroupId=com.yxkong -DarchetypeArtifactId=ddd-archetype -DarchetypeVersion=0.1 -DgroupId=com.yxkong -DartifactId=user-ddd -Dpackage=com.yxkong.user  -Dversion=1.0  -DappName=user -DupperAppName=User -X  -DarchetypeCatelog=local -s /Users/yxk/javaServer/maven/apache-maven-3.6.3/conf/settings-aliyun.xml


If the following error is reported: there is a pom file in the current directory when the generate command is executed

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-archetype-plugin:3.2.0:generate (default-cli) on project ddd-archetype: Unable to add module to the current project as it is not of packaging type 'pom' -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-archetype-plugin:3.2.0:generate (default-cli) on project ddd-archetype: Unable to add module to the current project as it is not of packaging type 'pom'

The generated project directory is as follows:

Modified archetype-metadata.xml

<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor xsi:schemaLocation="https://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.1.0 http://maven.apache.org/xsd/archetype-descriptor-1.1.0.xsd" name="ddd-archetype"
    xmlns="https://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <requiredProperties>
    <requiredProperty key="appName">
      <defaultValue>demo</defaultValue>
    </requiredProperty>
    <requiredProperty key="upperAppName">
      <defaultValue>Demo</defaultValue>
    </requiredProperty>
    <requiredProperty key="author">
      <defaultValue>yxkong</defaultValue>
    </requiredProperty>
    <requiredProperty key="webPort">
      <defaultValue>8001</defaultValue>
    </requiredProperty>
    <requiredProperty key="dbName">
      <defaultValue>user</defaultValue>
    </requiredProperty>
  </requiredProperties>
  <fileSets>
    <fileSet filtered="true" encoding="UTF-8">
      <directory>doc/init</directory>
      <includes>
        <include>**/*.sql</include>
      </includes>
    </fileSet>
    <fileSet filtered="true" encoding="UTF-8">
      <directory>doc</directory>
      <includes>
        <include>**/*.yml</include>
      </includes>
    </fileSet>
    <fileSet filtered="true" encoding="UTF-8">
      <directory>doc/nacos</directory>
      <includes>
        <include>**/*.properties</include>
      </includes>
    </fileSet>
    <fileSet encoding="UTF-8">
      <directory>doc/conf</directory>
      <includes>
        <include>**/*.log</include>
        <include>**/*.cnf</include>
        <include>**/*.conf</include>
      </includes>
    </fileSet>
    <fileSet encoding="UTF-8">
      <directory>ssh</directory>
      <includes>
        <include>**/*.sh</include>
      </includes>
    </fileSet>
    <fileSet encoding="UTF-8">
      <directory>doc</directory>
      <includes>
        <include>**/*.png</include>
      </includes>
    </fileSet>
    <fileSet encoding="UTF-8">
      <directory>doc/nacos</directory>
      <includes>
        <include>**/*.env</include>
      </includes>
    </fileSet>
    <fileSet encoding="UTF-8">
      <directory></directory>
      <includes>
        <include>readme.md</include>
        <include>.gitignore</include>
      </includes>
    </fileSet>
  </fileSets>
  <modules>
    <!--
     dir It's a real directory. It's what it is. It won't be parsed. When it's generated, get the template from this directory
     id And name are the module names to be generated
    -->
    <module id="${appName}-adapter" dir="__appName__-adapter" name="${appName}-adapter">
      <fileSets>
        <!-- Do not add packaged="true". If it is added, the package package will be added in the corresponding directory -- >
        <fileSet filtered="true" encoding="UTF-8">
          <directory>src/main/java</directory>
          <includes>
            <include>**/*.java</include>
            <include>**/*.gitkeep</include>
          </includes>
        </fileSet>
        <fileSet filtered="true" encoding="UTF-8">
          <directory>src/main/resources</directory>
          <includes>
            <include>**/*.yml</include>
          </includes>
        </fileSet>
        <fileSet encoding="UTF-8">
          <directory></directory>
          <includes>
            <include>.gitignore</include>
          </includes>
        </fileSet>
      </fileSets>
    </module>
    <module id="${appName}-application" dir="__appName__-application" name="${appName}-application">
      <fileSets>
        <fileSet filtered="true" packaged="true" encoding="UTF-8">
          <directory>src/main/java</directory>
          <includes>
            <include>**/*.java</include>
            <include>**/*.gitkeep</include>
          </includes>
        </fileSet>
        <fileSet encoding="UTF-8">
          <directory></directory>
          <includes>
            <include>.gitignore</include>
          </includes>
        </fileSet>
      </fileSets>
    </module>
    <module id="${appName}-infrastructure" dir="__appName__-infrastructure" name="${appName}-infrastructure">
      <fileSets>
        <fileSet filtered="true" packaged="true" encoding="UTF-8">
          <directory>src/main/java</directory>
          <includes>
            <include>**/*.java</include>
            <include>**/*.gitkeep</include>
          </includes>
        </fileSet>
        <fileSet filtered="true" encoding="UTF-8">
          <directory>src/main/resources</directory>
          <includes>
            <include>**/*.yml</include>
            <include>**/*.xml</include>
          </includes>
        </fileSet>
        <fileSet filtered="true" packaged="true" encoding="UTF-8">
          <directory>src/test/java</directory>
          <includes>
            <include>**/*.java</include>
          </includes>
        </fileSet>
        <fileSet encoding="UTF-8">
          <directory></directory>
          <includes>
            <include>.gitignore</include>
          </includes>
        </fileSet>
      </fileSets>
    </module>
    <module id="${appName}-domain" dir="__appName__-domain" name="${appName}-domain">
      <fileSets>
        <fileSet filtered="true" packaged="true" encoding="UTF-8">
          <directory>src/main/java</directory>
          <includes>
            <include>**/*.java</include>
            <include>**/*.gitkeep</include>
          </includes>
        </fileSet>
        <fileSet encoding="UTF-8">
          <directory></directory>
          <includes>
            <include>.gitignore</include>
          </includes>
        </fileSet>
      </fileSets>
    </module>
  </modules>
</archetype-descriptor>


src/main/resources/archetype-resources/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>
    <parent>
        <groupId>com.yxkong</groupId>
        <artifactId>ddd-parent</artifactId>
        <version>0.1</version>
    </parent>
    <artifactId>${artifactId}</artifactId>
    <groupId>${groupId}</groupId>
    <packaging>pom</packaging>
    <version>${version}</version>
    <modules>
        <module>${appName}-adapter</module>
        <module>${appName}-application</module>
        <module>${appName}-infrastructure</module>
        <module>${appName}-domain</module>
    </modules>
    <properties>
        <argLine>-Dfile.encoding=UTF-8</argLine>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>${groupId}</groupId>
                <artifactId>${appName}-adapter</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>${groupId}</groupId>
                <artifactId>${appName}-application</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>${groupId}</groupId>
                <artifactId>${appName}-infrastructure</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>${groupId}</groupId>
                <artifactId>${appName}-domain</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- Configure remote warehouse -->
    <distributionManagement>
        <repository>
            <id>aliyun</id>
            <url>https://maven.aliyun.com/nexus/content/groups/public/</url>
        </repository>
    </distributionManagement>
    <repositories>
        <repository>
            <id>aliyun-public</id>
            <name>aliyun-public</name>
            <url>https://maven.aliyun.com/nexus/content/groups/public/</url>
        </repository>
    </repositories>

    <build>
        <defaultGoal>compile</defaultGoal>
        <finalName>${project.artifactId}-${project.version}</finalName>
        <plugins>
            <!-- Compiling plug-ins -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                    <!--shield test-->
                    <skip>true</skip>
                    <!--Pass additional compile parameters-->
                    <compilerArgs>
                        <arg>-verbose</arg>
<!--                        <arg>-Xlint:all,-options,-path</arg>-->
                        <arg>-Xlint:unchecked</arg>
                        <arg>-Xlint:deprecation</arg>
                        <!--Add some jar,Give Way bootstrap ClassLoader load-->
<!--                        <arg>-Xbootclasspath:${java.home}/lib/rt.jar${path.separator}${java.home}/lib/jce.jar</arg>-->
                        <!--Resolve local jar Package dependency problem-->
<!--                        <arg>-Xextdirs:${basedir}\lib</arg>-->
                    </compilerArgs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <!--Prevent will.gitignore File ignore-->
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <addDefaultExcludes>false</addDefaultExcludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-archetype-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>



http://maven.apache.org/archetype/maven-archetype-plugin/

mvn archetype:generate Parameter description: 

-DarchetypeGroupId=com.yxkong   Scaffolding groupId
-DarchetypeArtifactId=ddd-archetype  Scaffolding artifactId
-DarchetypeVersion=0.1 Scaffold version
-DgroupId=com.xxx Projects to be generated groupId
-DartifactId=demo-archetype-generate Projects to be generated artifactId
-Dversion=1.0.0 Version number to be generated
-DarchetypeCatalog=internal Use of private warehouse scaffolding jar package, Premise: the scaffold has been released to the private warehouse

  remote,long-range Maven Templates provided in the library. mvn archetype:generate This type of template is used by default
  local,local Maven Templates provided in the library. mvn archetype:generate This type of template is used by default as remote Supplement to. Maven Initial value is empty, execute mvn install The current project will be added when local Template library
  internal,Apache Maven The default template provided by the project. mvn archetype:generate -DarchetypeCatalog=internal Use this type of template
  file://..., give a path on the local computer. Under this path, there is an archetype-catalog.xml file (which must be given if it is other file names), in which the template is configured
  
-DarchetypeCatalog=local Use local scaffolding jar package, If not configured, It will be downloaded from the central warehouse, Will lead to failure
-X debug pattern

Overall Code:

https://github.com/yxkong/ddd-framework

In the process of using, you can refer to the following

Docker compose installation development environment

Build the springboot project as a docker image

Tags: Maven architecture IDE

Posted on Sun, 28 Nov 2021 21:23:06 -0500 by erth