Skip to content

Commit 93f6a58

Browse files
author
Christoph Läubrich
committed
Add support for a process API
Maven Mojos (and maybe components) can create / fork processes, common examples would include: - ant-run plugin - maven-exec-plugin - maven-surefire currently the IDE has no effective way to know about forked processes, so there is no way to visualize them (e.g. in a process manager) nor to take special actions on them (e.g. automatically request to open a debug port). For executions of tests, the IDE even may want to be notified about individual test runs while the process is running. This now adds a new build-process API that mitigates the problem by allowing a mojo or component to make the IDE aware of subprocesses but is completely disabled if running outside an IDE. An integration can range from very basic, that is only notify that a process is running over to specialized callbacks that allows the IDE to intercept process creation in a generic way. An example implementation is provided for either resuse, extension or own implementation of such callbacks. To reflect this new opportunity, the minor version is increase to 1.3 even though neither consumers nor providers of the API need to take immediate actions here.
1 parent 48fe7ea commit 93f6a58

10 files changed

+470
-2
lines changed

README.md

+58-1
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,76 @@ Plexus Build API
77

88
This API allows IDEs to integrate with Maven deeper than it would be possible by just using regular Maven/Mojo API.
99

10+
## Marker and File Delta support
1011
It supports
1112

1213
- incremental builds e.g. allows to query which files have been touched since last build
1314
- fine-grained error/info markers (referring to specific files in particular line numbers)
1415
- notifications about updated files
1516

17+
## Process support
18+
19+
This API is located in the package `org.codehaus.plexus.build.process` and allows the IDE to interact with a mojo that starts new processes and has the following purposes:
20+
21+
- allow representation of processes in the UI e.g with a name and its current state together with a way to optionally terminate a running process
22+
- optionally decorate the process dependeing on the use case e.g. add additional environment variables, supply classpath entries or provide listeners
23+
24+
The main entry point for this is the `ProcessContext` that can be injected in a mojo in the follwoing way:
25+
26+
```
27+
public MyMojo extends AbstractMojo {
28+
29+
@Component
30+
private ProcessManager processContext;
31+
32+
public void execute() {
33+
34+
ProcessContext context = ...
35+
36+
BuildProcess process = processContext.newProcess(context);
37+
}
38+
}
39+
```
40+
41+
As one can see we have a `ProcessManager` that is capable of creating a Process for the user to see it in the IDE and the `BuildProcess` can be used to notify the IDE about process changes, e.g. if it is terminated.
42+
There is also a `ProcessContext` passed to the call that allow the mojo to supply basic information like the name or if it can be terminated but also can implements different callbacks that might (or might not) be called to furhter decorate the process.
43+
The follwoing callbacks are currently supported:
44+
45+
### ProcessCallback
46+
47+
`ProcessCallback` are quite bare callback that allow to request for adding (or replacing) an environment variable with `ProcessCallback#setEnvironmentVariable`,
48+
any context that support should implement the interface. Even though a request is made it could be reqjected, e.g because the context don't allow this because
49+
it uses a variable with the same name already and don'T want to replace it.
50+
51+
A basic implementation of this is provided with `ProcessBuilderContext` what implements this using a ProcessBuilder, so if processes are currently implemented that way it can be reused.
52+
53+
### JavaCallback
54+
55+
`JavaCallback` offers specialized way to add options to a launch that is running in a JVM (either directly or forked). The possible callbacks are
56+
57+
- setSystemProperty for requesting to add (or replace) a system property
58+
- setVMOption for requesting to add (or replace) a VM option
59+
- addClasspathEntry for requesting to add a new jar on the classpath
60+
61+
There is currently no implementation added here but one can reuse `ProcessBuilderContext` for performin neccesary actions.
62+
63+
### JUnitCallback
64+
65+
`JUnitCallback` offer specialized option to a launch that is executing test using JUnit framework. The possible callbacks are
66+
67+
- addTestClasspathEntry for requesting to add a new jar on the test classpath
68+
- addTestExecutionListener for reuqest to add a new listener that is notified about test events
69+
- getJUnitVersion allows to query for the used JUnit version
1670

1771
Current Implementations
1872
-----
1973

2074
### Default Implementation
2175

22-
The default implementation shipping with this artifact is supposed to impose minimal overhead. It doesn't support incremental build and acts directly on the file system. Errors and warning are just logged through SLF4J.
76+
- Marker and File Delta support is supposed to impose minimal overhead. It doesn't support incremental build and acts directly on the file system. Errors and warning are just logged through SLF4J.
77+
- Process support is simply a no-op, it never will call any callbacks and just discards the name, all calls on the listener will simply do nothing
78+
79+
## Process support
2380

2481
### M2Eclipse
2582

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ See the Apache License Version 2.0 for the specific language governing permissio
2121
</parent>
2222

2323
<artifactId>plexus-build-api</artifactId>
24-
<version>1.2.1-SNAPSHOT</version>
24+
<version>1.3.0-SNAPSHOT</version>
2525

2626
<scm>
2727
<connection>scm:git:https://github.com/codehaus-plexus/plexus-build-api.git</connection>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2024 Christoph Läubrich
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+
* http://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+
package org.codehaus.plexus.build.process;
17+
18+
/**
19+
* A {@link BuildProcess} represents a process created inside a maven execution
20+
* that performs a specialized task and can be represented as something other
21+
* than a mojo executions, for example a mojo that executes tests in a forked VM
22+
* can handle multiple forks in one invocation. Also a process allows to be
23+
* controlled from the outside, e.g. the user can request to terminate it.
24+
*/
25+
public interface BuildProcess {
26+
27+
/**
28+
* @return the name of the process
29+
*/
30+
String getName();
31+
32+
/**
33+
* Notify the manager that the given process was started
34+
*/
35+
void notifyStarted();
36+
37+
/**
38+
* @return true if the process is requested to terminate or has already
39+
* terminated.
40+
*/
41+
boolean isTerminated();
42+
43+
/**
44+
* Notify the manager that the given process has finished with the given exit
45+
* code where an exit code of zero usually indicates a successful termination
46+
*
47+
* @param exitcode
48+
*/
49+
void notifyFinished(int exitcode);
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2024 Christoph Läubrich
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+
* http://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+
package org.codehaus.plexus.build.process;
17+
18+
/**
19+
* A {@link BuildProcessContext} is used to create a {@link BuildProcess}, it
20+
* can implement any number of specialized callbacks that allow to further
21+
* customize the about to executed process, that allows IDEs to install
22+
* additional code to track progress or getting notified about results.
23+
*/
24+
public interface BuildProcessContext {
25+
26+
/**
27+
* Provides the name of process that is created, this is something that might be
28+
* presented to the user in an IDE
29+
*
30+
* @return the name
31+
*/
32+
String getName();
33+
34+
/**
35+
* Determines if termination of this process is possible, an IDE will possibly
36+
* present a way to terminate an individual process. A request to terminate the
37+
* process is then reflected in the process but it is the responsibility of the
38+
* implementation to act on it.
39+
*
40+
* @return <code>true</code>
41+
*/
42+
boolean canTerminate();
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2024 Christoph Läubrich
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+
* http://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+
package org.codehaus.plexus.build.process;
17+
18+
import java.nio.file.Path;
19+
20+
/**
21+
* Callback targeting a JUnit execution.
22+
*/
23+
public interface JUnitCallback {
24+
25+
enum JUnitVersion {
26+
JUNIT3,
27+
JUNIT4,
28+
JUNIT5;
29+
}
30+
31+
/**
32+
* Request to add a new classpath entry to the junit execution, this might
33+
* contain additional classes needed to perform some actions.
34+
*
35+
* @param extraTestClasspath the extra classpath element
36+
*
37+
* @return <code>true</code> if the request was accepted, <code>false</code>
38+
* otherwise.
39+
*/
40+
boolean addTestClasspathEntry(Path extraTestClasspath);
41+
42+
/**
43+
* Request to add a new TestExecutionListener specified by the full qualified
44+
* class name, this must either be a default one or one that can be loaded by
45+
* the extra test classpath added before.
46+
*
47+
* @param fqcn full qualified classname of the listener implementation
48+
* @return <code>true</code> if the listener was accepted, <code>false</code>
49+
* otherwise.
50+
*/
51+
boolean addTestExecutionListener(String fqcn);
52+
53+
/**
54+
* @return the version of JUnit that will be executed
55+
*/
56+
JUnitVersion getJUnitVersion();
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2024 Christoph Läubrich
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+
* http://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+
package org.codehaus.plexus.build.process;
17+
18+
import java.nio.file.Path;
19+
20+
/**
21+
* A callback for a context that is working around java processes to be started,
22+
* a {@link BuildProcessContext} should implement this if it allows to further
23+
* customize a process that is running a java VM. Depending on the launch type
24+
* (e.g embedded or forked) some options might not be possible and can maybe
25+
* rejected.
26+
*/
27+
public interface JavaCallback {
28+
29+
/**
30+
* Request to add a system property to the launch.
31+
*
32+
* @param key the key
33+
* @param value the value
34+
* @return <code>true</code> if the request was accepted, false otherwise.
35+
*/
36+
boolean setSystemProperty(String key, String value);
37+
38+
/**
39+
* Request to add a VM option to the launch.
40+
*
41+
* @param option the VM option to add
42+
* @param value the value or <code>null</code> if this option has no value
43+
* @return <code>true</code> if the request was accepted, false otherwise.
44+
*/
45+
boolean setVMOption(String option, String value);
46+
47+
/**
48+
* Request to add a new classpath entry to the launch
49+
*
50+
* @param extraClasspath the extra classpath element
51+
*
52+
* @return <code>true</code> if the request was accepted, false otherwise.
53+
*/
54+
boolean addClasspathEntry(Path extraClasspath);
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2024 Christoph Läubrich
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+
* http://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+
package org.codehaus.plexus.build.process;
17+
18+
/**
19+
* A {@link ProcessCallback} can be implemented by a context if it is able to
20+
* accept additional environment variables to be set on a process they create.
21+
*/
22+
public interface ProcessCallback {
23+
24+
/**
25+
* Request to set an additional environment variable, the context provider is
26+
* free to reject the request
27+
*
28+
* @param variable
29+
* @param value
30+
* @return <code>true</code> if the context accepted the request and will add
31+
* the environment variable to the launch, false otherwise.
32+
*/
33+
boolean setEnvironmentVariable(String variable, String value);
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2024 Christoph Läubrich
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+
* http://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+
package org.codehaus.plexus.build.process;
17+
18+
/**
19+
* The {@link ProcessManager} is responsible for connecting a process created by
20+
* a mojo (usually a forked one but thats not required) to the IDE and allows
21+
* some visual representation but also some customization using callbacks.
22+
*/
23+
public interface ProcessManager {
24+
25+
/**
26+
* Create a new {@link BuildProcess} given the {@link BuildProcessContext}
27+
* calling any supported callbacks.
28+
*
29+
* @param context the context to use
30+
* @return the created {@link BuildProcess} that can be used to further control
31+
* the process e.g inform about termination or <code>null</code> if no
32+
* process can be created, for example this can happen because required
33+
* callbacks are not supported for this kind of launch.
34+
*/
35+
BuildProcess newProcess(BuildProcessContext context);
36+
}

0 commit comments

Comments
 (0)