Table of contents
1 何謂 Maven shared libraries
顧名思義,Maven shared libraries 就係可以畀唔同 Maven projects 共用既 Maven libraries。一般黎講,shared libraries 都會提供一啲有特定用途既 public API classes。
1.1 3rd party Maven library 例子
- Apache Commons Lang
- Apache Commons IO
- Google Guava
2 Best practices
- 所有 public 既 Java classes 都要寫 Javadoc,因為用家可能會睇。
- 所有 public 既 Java methods 都要寫 Javadoc,因為用家可能會睇。
- 應該提供埋包含 Java source code 既 JAR 檔。
- 應該提供埋包含 Javadoc HTML 既 JAR 檔。
- 應該要寫 unit tests,最好有 full code coverage,覆蓋到所有或者大部分 branches(conditions),亦要出到 report,喺 CI/CD pipeline 平台(例如 Jenkins、GitHub Actions)上面睇到。
3 動手寫
Project structure:
3.1 Maven POM
1<?xml version="1.0" encoding="UTF-8"?>
2<project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6
7 <groupId>com.michael</groupId>
8 <artifactId>mick-math-lib</artifactId>
9 <version>1.0.0</version>
10 <packaging>jar</packaging>
11
12 <name>mick-math-lib</name>
13 <description>This is Michael's shared library for Math calculations.</description>
14
15 <properties>
16 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
18 <java.version>17</java.version>
19 <javac.source>17</javac.source>
20 <javac.target>17</javac.target>
21 <maven.compiler.target>17</maven.compiler.target>
22 <maven.compiler.source>17</maven.compiler.source>
23 </properties>
24
25 <dependencies>
26 <dependency>
27 <groupId>junit</groupId>
28 <artifactId>junit</artifactId>
29 <version>4.13.2</version>
30 <scope>test</scope>
31 </dependency>
32 </dependencies>
33
34 <build>
35 <plugins>
36 <plugin>
37 <groupId>org.apache.maven.plugins</groupId>
38 <artifactId>maven-source-plugin</artifactId>
39 <version>3.3.1</version>
40 <executions>
41 <execution>
42 <id>attach-sources</id>
43 <phase>package</phase>
44 <goals>
45 <goal>jar-no-fork</goal>
46 </goals>
47 </execution>
48 </executions>
49 </plugin>
50
51 <plugin>
52 <groupId>org.apache.maven.plugins</groupId>
53 <artifactId>maven-javadoc-plugin</artifactId>
54 <version>3.6.3</version>
55 <executions>
56 <execution>
57 <id>attach-javadoc</id>
58 <phase>package</phase>
59 <goals>
60 <goal>jar</goal>
61 </goals>
62 </execution>
63 </executions>
64 </plugin>
65
66 <plugin>
67 <groupId>org.jacoco</groupId>
68 <artifactId>jacoco-maven-plugin</artifactId>
69 <version>0.8.12</version>
70 <executions>
71 <execution>
72 <goals>
73 <goal>prepare-agent</goal>
74 </goals>
75 </execution>
76 <execution>
77 <id>jacoco-coverage</id>
78 <phase>test</phase>
79 <goals>
80 <goal>report</goal>
81 </goals>
82 </execution>
83 </executions>
84 </plugin>
85 </plugins>
86 </build>
87</project>
3.2 寫 Java code
喺寫 code 既同時,都要寫埋 Javadoc(/** */
裡面既野)。
MickMathUtils.java
:
1package code;
2
367
8public class MickMathUtils {
9
10 13141516
17 public int add(int a, int b) {
18 return a + b;
19 }
20
21 2425262728
29 public int divide(int a, int b) throws IllegalArgumentException {
30
31 if (b == 0) {
32 throw new IllegalArgumentException("Divisor cannot be zero!");
33 }
34
35 return a / b;
36 }
37}
4 Unit testing
我地會寫足以達到 100% code coverage 既 unit tests。要達到 100% code coverage,必須覆蓋到所有 if-else logical conditions。
4.1 寫 JUnit test class
MickMathUtilsTest.java
:
1package code;
2
3import org.junit.Assert;
4import org.junit.Test;
5
6public class MickMathUtilsTest {
7
8 @Test
9 public void test_add() {
10 final int sum = new MickMathUtils().add(2, 5);
11 Assert.assertEquals("Incorrect sum", 7, sum);
12 }
13
14 @Test
15 public void test_divide() {
16 final int product = new MickMathUtils().divide(10, 2);
17 Assert.assertEquals("Incorrect quotient", 5, product);
18 }
19
20 @Test
21 public void test_divide_byZero() {
22 try {
23 new MickMathUtils().divide(10, 0);
24 Assert.fail();
25 } catch (IllegalArgumentException e) {
26 // expected
27 }
28 }
29}
4.2 Eclipse IDE JUnit code coverage
開發既時候,我地可以利用 Eclipse IDE,喺執行 JUnit unit testing 既時候睇到 unit test 既 code coverage:
5 本地安裝/上載 remote repo
執行 command 安裝到本地 Maven repo:
mvn clean test install
或者上載埋去 remote repo:
mvn clean test install deploy
5.1 Jacoco coverage report
執行完 mvn test
就會生成到 Jacoco coverage HTML report。
我地可以打開 target/site/jacoco/index.html
:
6 喺另一個項目使用 shared library
我地會寫一個 Spring Boot web application 項目去用我地寫左既 Maven shared library。
6.1 Maven dependencies
1<parent>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-parent</artifactId>
4 <version>3.2.5</version>
5</parent>
6
7<dependencies>
8 <dependency>
9 <groupId>org.springframework.boot</groupId>
10 <artifactId>spring-boot-starter-web</artifactId>
11 </dependency>
12
13 <dependency>
14 <groupId>com.michael</groupId>
15 <artifactId>mick-math-lib</artifactId>
16 <version>1.0.0</version>
17 </dependency>
18</dependencies>
6.2 寫 Java code
MyController.java
:
1@RestController
2public class MyController {
3
4 @GetMapping("/add")
5 public int add(@RequestParam("a") int a, @RequestParam("b") int b) {
6 return new MickMathUtils().add(a, b);
7 }
8
9 @GetMapping("/divide")
10 public int divide(@RequestParam("a") int a, @RequestParam("b") int b) {
11 return new MickMathUtils().divide(a, b);
12 }
13}
6.2.1 檢視 shared library Java source code
Ctrl + click 落 MickMathUtils
既話,Eclipse IDE 會帶我地去 MickMathUtils.class
,而因為有 mick-math-lib-1.0.0-sources.jar
,就可以顯示到原本既 Java source code,唔需要用到 decompiler。
6.2.2 檢視 shared library Javadoc
因為有 mick-math-lib-1.0.0-javadoc.jar
,我地可以叫 Eclipse IDE 喺瀏覽器開個 Javadoc 網頁出黎。
Package Explorer > 個 Spring Boot web app project > Maven Dependencies > mick-math-lib-1.0.0.jar
> rick-click > Maven > Open Javadoc。
7 參考資料