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.json
and 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
__projectFolder
should 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.xml
and 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.xml
and 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.py
and 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