There are several ways to create project. It can be done by IDE default wizard or generate via spring initializer. Even these are convenient to us to setup project, but for organization it might has some custom libraries and organization-specific settings (e.g. private repositories, etc)
In this article, we will show how to create a project to support both Maven and Gradle.
This demo will use folder named java-project-template as example.
Prerequisites
- Python and cookiecutter should be installed properly.
// Install Python sudo apt install -y python // Install CookieCutter pip install cookiecutter
Steps
- Create CookieCutter project structure.
In command prompt, execute command below:mkdir {{cookiecutter.__projectFolder}} mkdir hooks - Create
cookiecutter.json
In the same folder, create file namedcookiecutter.jsonand input content as below:{ "javaVersion": ["17", "19", "11", "1.8"], "projectType": ["gradle", "maven"], "group": "io.github", "artifact": "demo-library", "version": "1.0.0-SNAPSHOT", "__projectName": "{{cookiecutter.group}}.{{cookiecutter.artifact}}", "__projectFolder" : "{{cookiecutter.artifact}}", "__projectPackageRoot" : "{{cookiecutter.group.lower()}}.{{cookiecutter.artifact.lower().replace('-','.') }}", }Remind that property
__projectFoldershould be same as the folder name in step 1, otherwise it cannot be render. - Create project template structure.
In command prompt, execute command below:cd {{cookiecutter.__projectFolder}} mkdir gradle mkdir src/main mkdir src/test - Create maven related file.
In folder{{cookiecutter.__projectFolder}}, create file namedpom.xmland input content below:<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>{{cookiecutter.group}}</groupId> <artifactId>{{cookiecutter.artifact}}</artifactId> <version>{{cookiecutter.version}}</version> <name>{{cookiecutter.__projectName}}</name> <properties> <maven.compiler.source>{{cookiecutter.javaVersion}}</maven.compiler.source> <maven.compiler.target>{{cookiecutter.javaVersion}}</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <junit-version>latest</junit-version> <mockito.version>latest</mockito.version> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.junit/junit-bom --> <dependency> <groupId>org.junit</groupId> <artifactId>junit-bom</artifactId> <version>${junit-version}</version> <type>pom</type> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>${mockito.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-inline</artifactId> <version>${mockito.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>3.5.0</version> <configuration> <reportOutputDirectory>docs</reportOutputDirectory> <destDir>docs</destDir> </configuration> </plugin> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.9</version> <configuration> <excludes> <exclude>docs/**</exclude> </excludes> </configuration> <executions> <execution> <id>prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> <version>8.2.1</version> <executions> <execution> <goals> <goal>check</goal> </goals> </execution> </executions> <configuration> <name>Dependency Check Report</name> <formats> <format>HTML</format> <format>JSON</format> </formats> </configuration> </plugin> <plugin> <groupId>org.sonarsource.scanner.maven</groupId> <artifactId>sonar-maven-plugin</artifactId> <version>3.9.1.2184</version> </plugin> </plugins> </pluginManagement> </build> </project> - Create Gradle related file.
In folder{{cookiecutter.__projectFolder}}, create file namedpom.xmland input content below:plugins { id("java") id("org.owasp.dependencycheck") version "8.2.1" } group = "{{cookiecutter.group}}.{{cookiecutter.artifact}}" version = "{{cookiecutter.version}}" repositories { mavenCentral() } dependencies { testImplementation(platform("org.junit:junit-bom:5.1.0")) testImplementation("org.junit.jupiter:junit-jupiter") } tasks.test { useJUnitPlatform() } tasks.withType<Javadoc> { val javaSrcDir = project.file("src/main/java") source = project.files(javaSrcDir).asFileTree classpath += project.files(sourceSets["main"].output) destinationDir = project.file("docs/javadoc") } - Create post render script.
In folderhook, create file namedpost_gen_project.pyand input as below:import os; def init_directories(): print("Initialize main program.") mainRootDirectory = "src/main/java/"+"{{cookiecutter.__projectPackageRoot}}".lower().replace(".", "/") os.makedirs(mainRootDirectory) os.rename("src/main/package-info.java", mainRootDirectory+"/package-info.java") os.rename("src/main/Main.java", mainRootDirectory+"/Main.java") print("Initialize test program.") testRootDirectory = "src/test/java/"+"{{cookiecutter.__projectPackageRoot}}".lower().replace(".", "/") os.makedirs(testRootDirectory) os.rename("src/test/package-info.java", testRootDirectory+"/package-info.java") os.rename("src/test/MainTest.java", testRootDirectory+"/MainTest.java") print("Clean up project.") match "{{cookiecutter.projectType}}": case "gradle": cleanup_maven() case "maven": cleanup_gradle() def cleanup_maven(): os.remove("pom.xml") os.remove(".github/workflows/CI-Maven.yaml") def cleanup_gradle(): os.rmdir("gradle") os.remove("build.gradle.kts") os.remove("gradlew") os.remove("gradlew.bat") os.remove("settings.gradle.kts") os.remove(".github/workflows/CI-Gradle.yaml") def main(): init_directories() if __name__ == "__main__": main()Method
init_directories()is used to create package structure with package name provided; And it will clean up unused files. - Test.
In command prompt, execute command below, exepect project will be render.cookiecutter java-project-template

Sample project has been store in GitHub repository.
Leave a Reply