pom example

scala

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<!-- properties -->
<properties>
<scala.version>2.12.7</scala.version>
<scala.compat.version>2.12</scala.compat.version>
<encoding>UTF-8</encoding>
</properties>

<!-- dependencies -->
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>org.scala-lang.modules</groupId>
<artifactId>scala-xml_${scala.compat.version}</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.scala-lang.modules</groupId>
<artifactId>scala-parser-combinators_${scala.compat.version}</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.scala-lang.modules</groupId>
<artifactId>scala-swing_${scala.compat.version}</artifactId>
<version>2.0.3</version>
</dependency>
</dependencies>

<!-- plugins -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<fork>true</fork>
<verbose>true</verbose>
<encoding>UTF-8</encoding>
<compilerArguments>
<sourcepath>
${project.basedir}/src/main/java
</sourcepath>
<sourcepath>
${project.basedir}/src/main/scala
</sourcepath>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.*.Class</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>

example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.neu.cse</groupId>
<artifactId>PowerCloud</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>PowerCloud Maven Webapp</name>

<!-- 集中定义依赖版本号 -->
<properties>
<junit.version>4.12</junit.version>
<spring.version>4.1.3.RELEASE</spring.version>
<mybatis.version>3.2.8</mybatis.version>
<mybatis.spring.version>1.2.2</mybatis.spring.version>
<mybatis.paginator.version>1.2.15</mybatis.paginator.version>
<mysql.version>5.1.32</mysql.version>
<slf4j.version>1.6.4</slf4j.version>
<jackson.version>2.4.2</jackson.version>
<druid.version>1.0.9</druid.version>
<httpclient.version>4.3.5</httpclient.version>
<jstl.version>1.2</jstl.version>
<servlet-api.version>2.5</servlet-api.version>
<jsp-api.version>2.0</jsp-api.version>
<joda-time.version>2.5</joda-time.version>
<commons-lang3.version>3.3.2</commons-lang3.version>
<commons-io.version>1.3.2</commons-io.version>
<commons-net.version>3.3</commons-net.version>
<pagehelper.version>3.4.2</pagehelper.version>
<jsqlparser.version>0.9.1</jsqlparser.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
</properties>

<dependencies>
<!-- 时间操作组件 -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${joda-time.version}</version>
</dependency>
<!-- Apache工具组件 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>${commons-net.version}</version>
</dependency>
<!-- Jackson Json处理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
<version>${mybatis.paginator.version}</version>
</dependency>

<!-- Pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency>

<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- 资源文件拷贝插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- java编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
<url>http://127.0.0.1:8080/manager/text</url>
<username>tomcat</username>
<password>tomcat</password>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<!-- 如果不添加此节点mybatis的mapper.xml文件都会被漏掉。 -->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<!-- 由于以上修改了resource目录,如果不添加此节点将无法扫描到applicationContext文件都会被漏掉。 -->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>

maven pom

Maven是什么

Apache Maven是一个软件项目管理和综合工具,基于项目对象模型(POM)的概念,Maven可以从一个中心资料片管理项目构建,报告和文件.

  • Maven提供给开发人员构建一个完整生命周期框架.开发团队可以自动完成项目的基础工具建设,Maven使用标准的目录结构和默认构建生命周期.
  • 在多个开发团队环境时,Maven可以设置按标准在非常短的时间里完成配置工作.由于大部分项目的设置都很简单,并且可重复使用,Maven让开发人员的工作更轻松,同时创建报表,检查,构建和测试自动化设置.
  • Maven提供了开发人员的方式来管理:
    • Builds
    • Documentation
    • Reporting
    • Dependencies
    • SCMs
    • Releases
    • Distribution
    • mailing list
  • 概括地说,Maven简化和标准化项目建设过程.处理编译,分配,文档,团队协作和其他任务的无缝连接.Maven增加可重用性并负责建立相关的任务.

Maven目标

Maven主要目标是提供给开发人员:

  • 项目是可重复使用,易维护,更容易理解的一个综合模型
  • 插件或交互的工具,这种声明性的模式

Maven项目的结构和内容在一个XML文件中声明,pom.xml 项目对象模型(POM),这是整个Maven系统的基本单元.有关详细信息,请参阅Maven POM的部分.

Apache Maven 是一种创新的软件项目管理工具,提供了一个项目对象模型(POM)文件的新概念来管理项目的构建,相关性和文档.最强大的功能就是能够自动下载项目依赖库.

Maven启用代理访问

  • 找到文件{M2_HOME}/conf/settings.xml

  • 找到下列代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <!-- proxies
    | This is a list of proxies which can be used on this machine to connect to the network.
    | Unless otherwise specified (by system property or command-line switch), the first proxy
    | specification in this list marked as active will be used.
    |-->
    <proxies>
    <!-- proxy
    | Specification for one proxy, to be used in connecting to the network.
    |
    <proxy>
    <id>optional</id>
    <active>true</active>
    <protocol>http</protocol>
    <username>proxyuser</</username>
    <password>proxypass</password>
    <host>proxy.host.net</host>
    <port>80</port>
    <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
    </proxy>
    -->
    </proxies>
  • 修改将上述代码,设置代理服务器

Maven本地资源库

Maven的本地资源库是用来存储所有项目的依赖关系(插件jar和其他文件,这些文件被Maven下载)到本地文件夹.

更新Maven的本地库

  • 找到文件{M2_HOME}/conf/settings.xml

  • 修改如下代码:

    1
    2
    3
    4
    5
    6
    <settings><!-- localRepository
    | The path to the local repository maven will use to store artifacts.
    |
    | Default: ~/.m2/repository
    <localRepository>/path/to/local/repo</localRepository>
    --><localRepository>D:\software\apache-maven\repository</localRepository>

Maven中央储存库

当你建立一个 Maven 的项目,Maven 会检查你的 pom.xml 文件,以确定哪些依赖下载.首先,Maven 将从本地资源库获得 Maven 的本地资源库依赖资源,如果没有找到,然后把它会从默认的 Maven 中央存储库 查找下载.

从Maven远程存储库下载

Maven的依赖库查询顺序:

  1. 在 Maven 本地资源库中搜索,如果没有找到,进入第 2 步,否则退出

  2. 在 Maven 中央存储库搜索,如果没有找到,进入第 3 步,否则退出

  3. 在给定url的远程存储库搜索,如果没有找到,提示错误信息,否则退出

给定URL的远程库

1
2
3
4
5
6
<repositories>
<repository>
<id>java.net</id>
<url>https://maven.java.net/content/repositories/public/</url>
</repository>
</repositories>

如果不注明version, maven将保持包是最新版本

定制库到Maven本地资源库

将本地的jar包导入到Maven本地资源库(以kaptcha为例):

  1. 找到kaptcha jar包所在位置

  2. 使用mvn命令安装到本地资源库:

    1
    mvn install:install-file -Dfile=c:\kaptcha-{version}.jar -DgroupId=com.google.code -DartifactId=kaptcha -Dversion={version} -Dpackaging=jar

    示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    D:\>mvn install:install-file -Dfile=c:\kaptcha-2.3.jar -DgroupId=com.google.code 
    -DartifactId=kaptcha -Dversion=2.3 -Dpackaging=jar
    [INFO] Scanning for projects...
    [INFO] Searching repository for plugin with prefix: 'install'.
    [INFO] ------------------------------------------------------------------------
    [INFO] Building Maven Default Project
    [INFO] task-segment: [install:install-file] (aggregator-style)
    [INFO] ------------------------------------------------------------------------
    [INFO] [install:install-file]
    [INFO] Installing c:\kaptcha-2.3.jar to
    D:\maven_repo\com\google\code\kaptcha\2.3\kaptcha-2.3.jar
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESSFUL
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: < 1 second
    [INFO] Finished at: Tue May 12 13:41:42 SGT 2014
    [INFO] Final Memory: 3M/6M
    [INFO] ------------------------------------------------------------------------
  3. 安装完毕后,就在pom.xml中声明kaptcha的坐标:

    1
    2
    3
    4
    5
    <dependency>
    <groupId>com.google.code</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3</version>
    </dependency>

Maven依赖关系中Scope的作用

主要管理依赖的部署,目前scope可以有五个值:

  • **compile:**缺省值,适用于所有阶段,会随项目一期发布
  • **provided:**类似compile,期望JDK,容器或使用者会提供这个依赖
  • **runtime:**只在运行时使用,如JDBC驱动,适用于运行和测试阶段
  • **test:**只在测试时使用,用于编译和运行测试代码,不会随项目发布
  • **system:**类似provided,需要显式提供包含依赖的jar,Maven不会在Repository中查找它

使用

  • Run as -> Maven install
  • Run as -> Maven build... -> clean tomcat7:run

maven problems

项目RUL路径问题

解决访问WEB项目需要添加项目名称问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
<url>http://127.0.0.1:8080/manager/text</url>
<username>tomcat</username>
<password>tomcat</password>
</configuration>
</plugin>

maven project

Maven项目实践。

组织结构

1
2
3
4
project-parent
- project-foo
- project-bar
pom.xml

项目包含一个父项目,所有子模块parent指定为该项目。

DependencyManagement

  • 统一依赖版本
  • 方便依赖版本变更

revision

项目版本定义在父项目中的properties中,变量名为revision,子模块版本使用${revision}变量,并在父项目引用 flatten-maven-plugin 插件,更多可参考这里。这样,整个项目的版本号可通过revision变量来设置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.2.5</version>
<configuration>
<updatePomFile>true</updatePomFile>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>

maven settings

Minimal settings.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository/>
<interactiveMode/>
<usePluginRegistry/>
<offline/>
<pluginGroups/>
<servers/>
<mirrors/>
<proxies/>
<profiles/>
<activeProfiles/>
</settings>

aliyun

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository/>
<interactiveMode/>
<usePluginRegistry/>
<offline/>
<pluginGroups/>
<servers/>
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
<proxies/>
<profiles/>
<activeProfiles/>
</settings>

合并依赖包内 META-INF

打包成单体 jar 包

在很多场景下,需要将程序及依赖打包为单个 jar 包,方便部署、运行。打包成单体 jar 包,有多个插件可选,比如 maven-shade-pluginmaven-assembly-plugin

合并 META-INF/services

以 gRPC 为例,我们有一个依赖包,里面自定义了 NameResolver。

1
2
# META-INF/services/io.grpc.NameResolverProvider
pub.wii.cook.governance.nameresolver.DynamicNameResolverProvider

如果我们恰巧引用了另外一个依赖包(jetcd-core),里面定义了其他的 NameResolver。

1
2
3
# META-INF/services/io.grpc.NameResolverProvider
io.etcd.jetcd.resolver.DnsSrvResolverProvider
io.etcd.jetcd.resolver.IPResolverProvider

那么,在我们打包成单体 jar 时,将两个依赖包内的 META-INF/services/io.grpc.NameResolverProvider 合并为一个,这样打包后的程序在运行时才可以通过 SPI 机制,找到所有的扩展。

1
2
3
4
# 期望的打包后 META-INF/services/io.grpc.NameResolverProvider
io.etcd.jetcd.resolver.DnsSrvResolverProvider
io.etcd.jetcd.resolver.IPResolverProvider
pub.wii.cook.governance.nameresolver.DynamicNameResolverProvider

无论 maven-shade-plugin 还是 maven-assembly-plugin,默认配置都不支持合并,需要单独配置。

对于 maven-shade-plugin ,需要添加 transformer。

1
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>

对于 maven-assembly-plugin ,需要添加组装描述文件 assembly.xml,并启用 handler metaInf-services

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- assembly.xml -->
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0
http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>jar-with-dependencies</id>
<formats>
<format>jar</format>
</formats>

<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>

<containerDescriptorHandlers>
<containerDescriptorHandler>
<handlerName>metaInf-services</handlerName>
</containerDescriptorHandler>
</containerDescriptorHandlers>
</assembly>

配置示例

maven-shade-pluginmaven-assembly-plugin 配置,二选一。

maven-shade-plugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>pub.wii.cook.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

maven-assembly-plugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/assemble/assembly.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>pub.wii.cook.Main</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>

assembly.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0
http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>jar-with-dependencies</id>
<formats>
<format>jar</format>
</formats>

<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>

<containerDescriptorHandlers>
<containerDescriptorHandler>
<handlerName>metaInf-services</handlerName>
</containerDescriptorHandler>
</containerDescriptorHandlers>
</assembly>

参考

typora

插入图片

image-20210818230821747

  • 选择「复制到指定路径」+ 「./${filename}
  • 勾选「优先使用相对路径」

这样,不管是复制文件还是从剪切板复制图片,都会保存到文件同目录、同文件名下,引用的时候使用相对路径,这样,在上传到 git 仓库时,可以同步上传图片,并保持引用关系。

问题

激活失败

  1. 修改网络的 DNS 为 8.8.8.8

caddy usage

文档

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
localhost {
respond "caddy server"
}

http://git.example.com {
reverse_proxy 192.168.1.2:8000
}

http://doc.example.com:85 {
reverse_proxy 192.168.1.3:8000 {
header_down Location "^(http://doc.example.com)(.*)$" "$1:85$2"
}
}

注意

  • 如果监听端口是 80 或不设置端口(默认监听 80),那么在处理请求时,看做 http 协议请求
  • 如果监听端口是非 80,那么请求被当做 https 协议请求
  • 显式指定 http 协议,那么请求看做 http 协议处理
1
2
3
example.com { ... }            # http 协议
example.com:81 { ... } # https 协议
http://example.com:81 { ... } # http 协议

问题

跳转时端口丢失

原因是服务再返回请求设置 header 的 Location 字段时,没有把端口加进去,导致的现象是访问 http://doc.example.com:85 服务跳转到 http://doc.example.com/index,由于端口丢失,导致无法访问。

从两个思路解决问题。

  • 服务端,在返回时设置 header 的 Location 把 port 加上(http://doc.example.com:85/index
  • 代理服务器处理,处理方式是替换 response header 的 Location,加上端口

下面是 Caddy 的配置示例。

1
header_down Location "^(http://doc.example.com)(.*)$" "$1:85$2"
  • header_down,修改 response 的 header。相反,header_up 是修改请求 header
  • Location,response header 字段
  • "^(http://doc.example.com)(.*)$", 匹配域名和 path
  • "$1:85$2",在域名和 path 中间加端口

charles usage

安装 & 配置

下载 & 安装 charles

点击跳转

配置

chrome

下载插件 SwitchProxy,添加 charles 代理,并启用。

image-20210817102317584

转发 localhost

添加 host

/etc/hosts 中添加 127.0.0.1 charles.prx

image-20210817102356555

charles 中添加 Map Remote

image-20210817103825440

效果

image-20210817103752293

手机抓包

Charles 设置

Proxy 设置

image-20210818223551834

  • 打开「Proxy -> SSL Proxying Settings」

image-20210818223804406

  • 勾选「Enable SSL Proxying」
  • 添加 Location
    • Host:*
    • Port:*

image-20210818223918941

证书设置

image-20210818224040600

  • 点击 「Help -> Install Charles Root Certificate」
    • 安装证书,位置选择系统(不要选择 iCloud)
  • 在密钥串访问(Keychain Access)程序中修改 Charles 证书的信任配置
    • 改为始终信任(Always Trust)

image-20210818224514316

iPhone

  • 保证手机和电脑在统一局域网,或手机可通过 ip 访问电脑

设置代理

打开 iPhone 「设置 -> 无线局域网 -> 详情(已连接Wifi后的蓝色感叹号)-> 配置代理」,配置代理,ip 为开启 charles 的电脑 ip,port 为 charles 启动的代理端口,默认为 8888。

image-20210818225004433

设置证书

打开「Charles -> Help 」

image-20210818224708417

会有如下提示。

image-20210818224739823

在 safari 中访问网址 chls.pro/ssl ,允许下载证书,成功后会提示去设置中安装描述符。

image-20210818225555306

打开「设置 -> 通用 -> 描述文件 -> Charles Proxy CA」,安装证书。

image-20210818225625748

最后一步,启用证书。打开「设置 -> 通用 -> 关于手机 -> 证书信任设置 -> Charles Proxy CA」,启用它。

image-20210818225810942

brew

安装卸载

安装

使用清华开源站仓库安装参考这里

1
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

卸载

1
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

初始化

1
brew tap homebrew/cask-versions

软件

jdk

1
2
3
4
5
6
7
8
# openjdk
brew search jdk
brew install openjdk@8
# adoptopenjdk
brew tap adoptopenjdk/openjdk
brew search adoptopenjdk
brew install adoptopenjdk8
brew install adoptopenjdk # 最新 jdk

管理多个版本 jdk 参考这里

1
2
3
4
5
6
# 安装 jenv
brew install jenv
# 配置 jenv
echo 'eval "$(jenv init -)"' >> ~/.bash_profile
# 添加需要管理的的 jdk
jenv add /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home