Skip to content

Commit 4b68734

Browse files
timothyspargclaude
andcommitted
Add spring-javaformat-cli module
Introduces a new Spring Boot CLI module built on picocli. The module targets Java 17 and includes Error Prone and NullAway for compile-time null-safety enforcement via jspecify @NullMarked annotations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4286438 commit 4b68734

File tree

6 files changed

+323
-0
lines changed

6 files changed

+323
-0
lines changed

.mvn/jvm.config

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,14 @@
11
-Xmx1536m
22
-Dtycho.disableP2Mirrors=true
3+
-Djdk.xml.maxGeneralEntitySizeLimit=0
4+
-Djdk.xml.totalEntitySizeLimit=0
5+
--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
6+
--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
7+
--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
8+
--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
9+
--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
10+
--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
11+
--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
12+
--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
13+
--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
14+
--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED

pom.xml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,12 @@
4848
<mockito.version>3.6.28</mockito.version>
4949
<junit.version>5.8.1</junit.version>
5050
<javassist.version>3.21.0-GA</javassist.version>
51+
<jspecify.version>1.0.0</jspecify.version>
5152
<picocontainer.version>1.2</picocontainer.version>
53+
<picocli.version>4.7.7</picocli.version>
5254
<plexus-utils.version>3.5.1</plexus-utils.version>
55+
<spring-boot.version>2.7.18</spring-boot.version>
56+
<spring-native.version>0.12.2</spring-native.version>
5357
<system-rules.version>1.16.0</system-rules.version>
5458
<testcontainers.version>1.16.0</testcontainers.version>
5559
<trove4j.version>3.0.3</trove4j.version>
@@ -181,6 +185,16 @@
181185
<artifactId>maven-source-plugin</artifactId>
182186
<version>3.2.1</version>
183187
</plugin>
188+
<plugin>
189+
<groupId>org.springframework.boot</groupId>
190+
<artifactId>spring-boot-maven-plugin</artifactId>
191+
<version>${spring-boot.version}</version>
192+
</plugin>
193+
<plugin>
194+
<groupId>org.springframework.experimental</groupId>
195+
<artifactId>spring-aot-maven-plugin</artifactId>
196+
<version>${spring-native.version}</version>
197+
</plugin>
184198
<plugin>
185199
<groupId>org.apache.maven.plugins</groupId>
186200
<artifactId>maven-javadoc-plugin</artifactId>
@@ -495,6 +509,11 @@
495509
<artifactId>log4j-slf4j-impl</artifactId>
496510
<version>${log4j.version}</version>
497511
</dependency>
512+
<dependency>
513+
<groupId>org.jspecify</groupId>
514+
<artifactId>jspecify</artifactId>
515+
<version>${jspecify.version}</version>
516+
</dependency>
498517
<dependency>
499518
<groupId>org.junit</groupId>
500519
<artifactId>junit-bom</artifactId>
@@ -558,11 +577,21 @@
558577
<artifactId>picocontainer</artifactId>
559578
<version>${picocontainer.version}</version>
560579
</dependency>
580+
<dependency>
581+
<groupId>info.picocli</groupId>
582+
<artifactId>picocli-spring-boot-starter</artifactId>
583+
<version>${picocli.version}</version>
584+
</dependency>
561585
<dependency>
562586
<groupId>org.codehaus.plexus</groupId>
563587
<artifactId>plexus-utils</artifactId>
564588
<version>${plexus-utils.version}</version>
565589
</dependency>
590+
<dependency>
591+
<groupId>org.springframework.experimental</groupId>
592+
<artifactId>spring-native</artifactId>
593+
<version>${spring-native.version}</version>
594+
</dependency>
566595
<dependency>
567596
<groupId>org.testcontainers</groupId>
568597
<artifactId>testcontainers</artifactId>
@@ -595,6 +624,7 @@
595624
</dependencies>
596625
<modules>
597626
<module>spring-javaformat</module>
627+
<module>spring-javaformat-cli</module>
598628
<module>spring-javaformat-eclipse</module>
599629
<module>spring-javaformat-gradle</module>
600630
<module>spring-javaformat-intellij-idea</module>

spring-javaformat-cli/pom.xml

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>io.spring.javaformat</groupId>
7+
<artifactId>spring-javaformat-build</artifactId>
8+
<version>0.0.48-SNAPSHOT</version>
9+
</parent>
10+
<artifactId>spring-javaformat-cli</artifactId>
11+
<name>Spring JavaFormat CLI</name>
12+
<properties>
13+
<main.basedir>${basedir}/..</main.basedir>
14+
<maven.compiler.source>17</maven.compiler.source>
15+
<maven.compiler.target>17</maven.compiler.target>
16+
<java.version>17</java.version>
17+
</properties>
18+
19+
<dependencyManagement>
20+
<dependencies>
21+
<dependency>
22+
<groupId>org.springframework.boot</groupId>
23+
<artifactId>spring-boot-dependencies</artifactId>
24+
<version>${spring-boot.version}</version>
25+
<type>pom</type>
26+
<scope>import</scope>
27+
</dependency>
28+
</dependencies>
29+
</dependencyManagement>
30+
31+
<dependencies>
32+
<!-- Compile -->
33+
<dependency>
34+
<groupId>org.jspecify</groupId>
35+
<artifactId>jspecify</artifactId>
36+
</dependency>
37+
<dependency>
38+
<groupId>io.spring.javaformat</groupId>
39+
<artifactId>spring-javaformat-formatter</artifactId>
40+
<version>${project.version}</version>
41+
</dependency>
42+
<dependency>
43+
<groupId>io.spring.javaformat</groupId>
44+
<artifactId>spring-javaformat-formatter-eclipse-runtime</artifactId>
45+
<version>${project.version}</version>
46+
<exclusions>
47+
<exclusion>
48+
<groupId>*</groupId>
49+
<artifactId>*</artifactId>
50+
</exclusion>
51+
</exclusions>
52+
</dependency>
53+
<dependency>
54+
<groupId>io.spring.javaformat</groupId>
55+
<artifactId>spring-javaformat-config</artifactId>
56+
<version>${project.version}</version>
57+
</dependency>
58+
<dependency>
59+
<groupId>io.spring.javaformat</groupId>
60+
<artifactId>spring-javaformat-checkstyle</artifactId>
61+
<version>${project.version}</version>
62+
</dependency>
63+
<dependency>
64+
<groupId>org.springframework.experimental</groupId>
65+
<artifactId>spring-native</artifactId>
66+
</dependency>
67+
<dependency>
68+
<groupId>info.picocli</groupId>
69+
<artifactId>picocli-spring-boot-starter</artifactId>
70+
</dependency>
71+
<dependency>
72+
<groupId>org.codehaus.plexus</groupId>
73+
<artifactId>plexus-utils</artifactId>
74+
</dependency>
75+
76+
<!-- Test -->
77+
<dependency>
78+
<groupId>org.springframework.boot</groupId>
79+
<artifactId>spring-boot-starter-test</artifactId>
80+
<scope>test</scope>
81+
</dependency>
82+
</dependencies>
83+
84+
<build>
85+
<plugins>
86+
<plugin>
87+
<groupId>org.apache.maven.plugins</groupId>
88+
<artifactId>maven-javadoc-plugin</artifactId>
89+
<configuration>
90+
<source>${java.version}</source>
91+
</configuration>
92+
</plugin>
93+
<plugin>
94+
<groupId>org.apache.maven.plugins</groupId>
95+
<artifactId>maven-compiler-plugin</artifactId>
96+
<configuration>
97+
<parameters>true</parameters>
98+
<compilerArgs>
99+
<arg>-XDcompilePolicy=simple</arg>
100+
<arg>-XDaddTypeAnnotationsToSymbol=true</arg>
101+
<!-- Required by Error Prone 2.42.x on newer javac versions -->
102+
<arg>-XDshould-stop.ifError=FLOW</arg>
103+
<arg>-Xplugin:ErrorProne -XepDisableWarningsInGeneratedCode -Xep:NullAway:ERROR -XepOpt:NullAway:JSpecifyMode=true -XepOpt:NullAway:OnlyNullMarked=true -XepOpt:NullAway:ExternalInitAnnotations=io.spring.javaformat.cli.PicocliManaged</arg>
104+
<arg>-Aproject=${project.groupId}/${project.artifactId}</arg>
105+
</compilerArgs>
106+
<annotationProcessorPaths>
107+
<path>
108+
<groupId>info.picocli</groupId>
109+
<artifactId>picocli-codegen</artifactId>
110+
<version>4.7.7</version>
111+
</path>
112+
<!-- 2.42.0 is the last version compiled for Java 17; 2.43.0+ requires Java 21 -->
113+
<path>
114+
<groupId>com.google.errorprone</groupId>
115+
<artifactId>error_prone_core</artifactId>
116+
<version>2.42.0</version>
117+
</path>
118+
<!-- 0.12.11 is compatible with Error Prone 2.42.0 -->
119+
<path>
120+
<groupId>com.uber.nullaway</groupId>
121+
<artifactId>nullaway</artifactId>
122+
<version>0.12.11</version>
123+
</path>
124+
</annotationProcessorPaths>
125+
</configuration>
126+
</plugin>
127+
<plugin>
128+
<groupId>org.springframework.experimental</groupId>
129+
<artifactId>spring-aot-maven-plugin</artifactId>
130+
<executions>
131+
<execution>
132+
<id>generate</id>
133+
<goals>
134+
<goal>generate</goal>
135+
</goals>
136+
</execution>
137+
</executions>
138+
</plugin>
139+
<plugin>
140+
<groupId>org.springframework.boot</groupId>
141+
<artifactId>spring-boot-maven-plugin</artifactId>
142+
<configuration>
143+
<classifier>exec</classifier>
144+
</configuration>
145+
<executions>
146+
<execution>
147+
<goals>
148+
<goal>repackage</goal>
149+
</goals>
150+
</execution>
151+
</executions>
152+
</plugin>
153+
</plugins>
154+
</build>
155+
156+
<profiles>
157+
<profile>
158+
<id>native</id>
159+
<build>
160+
<plugins>
161+
<plugin>
162+
<groupId>org.graalvm.buildtools</groupId>
163+
<artifactId>native-maven-plugin</artifactId>
164+
<version>0.9.28</version>
165+
<extensions>true</extensions>
166+
<executions>
167+
<execution>
168+
<id>build-native</id>
169+
<phase>package</phase>
170+
<goals>
171+
<goal>build</goal>
172+
</goals>
173+
</execution>
174+
</executions>
175+
<configuration>
176+
<mainClass>io.spring.javaformat.cli.SpringJavaFormatCliApplication</mainClass>
177+
<buildArgs>
178+
<buildArg>--no-fallback</buildArg>
179+
<buildArg>--allow-incomplete-classpath</buildArg>
180+
<buildArg>--initialize-at-build-time=org.springframework.core.annotation.RepeatableContainers,org.springframework.core.annotation.RepeatableContainers$NoRepeatableContainers,org.springframework.core.annotation.TypeMappedAnnotations</buildArg>
181+
<buildArg>--initialize-at-build-time=io.spring.javaformat.eclipse.jdt.jdk17.internal.compiler</buildArg>
182+
</buildArgs>
183+
</configuration>
184+
</plugin>
185+
</plugins>
186+
</build>
187+
</profile>
188+
</profiles>
189+
190+
<repositories>
191+
<repository>
192+
<id>spring-milestones</id>
193+
<name>Spring Milestones</name>
194+
<url>https://repo.spring.io/milestone</url>
195+
<snapshots>
196+
<enabled>false</enabled>
197+
</snapshots>
198+
</repository>
199+
</repositories>
200+
<pluginRepositories>
201+
<pluginRepository>
202+
<id>spring-milestones</id>
203+
<name>Spring Milestones</name>
204+
<url>https://repo.spring.io/milestone</url>
205+
<snapshots>
206+
<enabled>false</enabled>
207+
</snapshots>
208+
</pluginRepository>
209+
</pluginRepositories>
210+
211+
</project>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2017-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.spring.javaformat.cli;
18+
19+
import org.springframework.boot.Banner;
20+
import org.springframework.boot.SpringApplication;
21+
import org.springframework.boot.autoconfigure.SpringBootApplication;
22+
23+
/**
24+
* Main application for the Spring JavaFormat CLI.
25+
*
26+
* @author Tim Sparg
27+
*/
28+
@SpringBootApplication
29+
public class SpringJavaFormatCliApplication {
30+
31+
protected SpringJavaFormatCliApplication() {
32+
}
33+
34+
public static void main(String[] args) {
35+
SpringApplication application = new SpringApplication(SpringJavaFormatCliApplication.class);
36+
application.setBannerMode(Banner.Mode.OFF);
37+
application.setLogStartupInfo(false);
38+
System.exit(SpringApplication.exit(application.run(args)));
39+
}
40+
41+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2017-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Spring JavaFormat CLI — command-line tool for applying and validating Java formatting.
19+
*
20+
* @author Tim Sparg
21+
*/
22+
@NullMarked
23+
package io.spring.javaformat.cli;
24+
25+
import org.jspecify.annotations.NullMarked;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
spring.main.web-application-type=none
2+
logging.level.root=ERROR
3+
logging.level.io.spring.javaformat=ERROR
4+
logging.level.org.springframework=ERROR

0 commit comments

Comments
 (0)