diffplug / diffplug/spotless

IDE hook crashes Maven 4

Aperta
#2,584 4 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
Java
Stelle
5.6k
Fork
559
Merge medio
1g 14h
PR unite (30g)
43

Descrizione

I am looking at developing a VSCode plugin for Spotless that works with Maven. For performance reasons I want to use `mvnd` which is a daemon-based version of Maven, and which is based on Maven 4.x.

I have found that on Maven 4, if I invoke:

```
$ mvn spotless:apply -DspotlessIdeHook=/home/jay/Projects/vscode-spotless-maven/test-project/src/main/java/com/mycompany/app/App.java
```

then it executes successfully but crashes Maven while cleaning up:

```
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------------------------------< com.mycompany.app:my-app >-----------------------------------------------
[INFO] Building my-app 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] ---------------------------------------------------------[ jar ]----------------------------------------------------------
[INFO]
[INFO] --- spotless:2.46.1:apply (default-cli) @ my-app ---
[WARNING] [stderr] IS CLEAN
[INFO] --------------------------------------------------------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] --------------------------------------------------------------------------------------------------------------------------
[INFO] Total time: 0.802 s
[INFO] Finished at: 2025-08-02T16:33:13+01:00
[INFO] --------------------------------------------------------------------------------------------------------------------------
[ERROR] Unable to close context
org.apache.maven.api.cli.InvokerException: Unable to close context
at org.apache.maven.cling.invoker.LookupContext.close(LookupContext.java:128)
at org.apache.maven.cling.invoker.LookupInvoker.invoke(LookupInvoker.java:143)
at org.apache.maven.cling.ClingSupport.run(ClingSupport.java:76)
at org.apache.maven.cling.MavenCling.main(MavenCling.java:51)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:565)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:255)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:201)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:361)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:314)
Suppressed: java.lang.NullPointerException: Cannot invoke "org.apache.maven.logging.LoggingOutputStream.forceFlush()" because "this.out" is null
at org.apache.maven.logging.LoggingOutputStream$LoggingPrintStream.forceFlush(LoggingOutputStream.java:88)
at org.apache.maven.logging.LoggingOutputStream.forceFlush(LoggingOutputStream.java:94)
at org.apache.maven.cling.invoker.LookupInvoker.lambda$doConfigureWithTerminalWithRawStreamsDisabled$3(LookupInvoker.java:378)
at org.apache.maven.cling.invoker.LookupContext.close(LookupContext.java:118)
... 9 more
Suppressed: java.lang.NullPointerException: Cannot invoke "org.apache.maven.logging.LoggingOutputStream.forceFlush()" because "this.out" is null
at org.apache.maven.logging.LoggingOutputStream$LoggingPrintStream.forceFlush(LoggingOutputStream.java:88)
at org.apache.maven.logging.LoggingOutputStream.forceFlush(LoggingOutputStream.java:94)
at org.apache.maven.cling.invoker.LookupInvoker.lambda$doConfigureWithTerminalWithRawStreamsDisabled$1(LookupInvoker.java:376)
at org.apache.maven.cling.invoker.LookupContext.close(LookupContext.java:118)
... 9 more
```

Note that Spotless doesn't crash Maven if you don't use the IDE hook.

I have been able to narrow this down to the following code in the Maven IDE hook:

https://github.com/diffplug/spotless/blob/7d5c826973a900713fe7b23ed20113b0c2c2315e/plugin-maven/src/main/java/com/diffplug/spotless/maven/IdeHook.java#L69-L72

I believe this code is the cause because if I make my own minimal mojo on Maven 4.x which looks like this:

```java
package sample.plugin;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;

@Mojo(name = "sayhi")
public class GreetingMojo extends AbstractMojo
{
@Override
public void execute() throws MojoExecutionException
{
getLog().info("Hello, world.");

System.err.close();
System.out.close();
}
}
```

then I am able to reproduce the same crash with `mvn sample.plugin:hello-maven-plugin:1.0-SNAPSHOT:sayhi`. If I then comment those two lines of code out, the crash disappears.

I wanted to ask why we need to close stdout/stderr after the IDE hook has finished? It might well be that this is a Maven issue rather than a Spotless issue (it doesn't feel like a plugin should be able to crash the host build system) but if we can do a quick fix here rather than waiting for a change in Maven that would be great.

## Issue template

spotless version: 2.46.1
maven version: Apache Maven 4.0.0-rc-4 (bed0f8174bf728978f86fac533aa38a9511f3872)
repro: https://github.com/SapiensAnatis/vscode-spotless-maven/tree/master/test-project (but any Spotless project will work fine if my understanding of the cause is correct)

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia da plugin-maven/src/main/java/com/diffplug/spotless/maven/IdeHook.java, alle righe indicate, quindi riproduci il problema con Maven 4 usando il comando mvn spotless:apply e il mojo minimo fornito che chiude stdout e stderr. Determina se l’hook dell’IDE deve ancora chiudere questi stream; il lavoro è completato quando l’invocazione di Maven 4 termina senza il crash di cleanup e l’hook dell’IDE continua a funzionare.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
java
Ambito
build-system, tooling
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.