0
# Plugin System
1
2
Maven Core's plugin system provides comprehensive APIs for managing, loading, configuring, and executing Maven plugins. This includes plugin discovery, classloader management, caching mechanisms, and execution coordination. The plugin system is central to Maven's extensible architecture.
3
4
## Core Plugin Management
5
6
### MavenPluginManager Interface
7
8
Primary interface for plugin management operations including plugin loading, realm setup, and Mojo configuration.
9
10
```java { .api }
11
public interface MavenPluginManager {
12
/**
13
* Get plugin descriptor for a plugin.
14
*
15
* @param plugin the plugin to get descriptor for
16
* @param repositories list of repositories to search
17
* @param session repository system session
18
* @return plugin descriptor containing plugin metadata
19
* @throws PluginDescriptorParsingException if descriptor parsing fails
20
* @throws InvalidPluginDescriptorException if descriptor is invalid
21
*/
22
PluginDescriptor getPluginDescriptor(Plugin plugin, List<RemoteRepository> repositories,
23
RepositorySystemSession session) throws PluginDescriptorParsingException, InvalidPluginDescriptorException;
24
25
/**
26
* Setup plugin classloader realm.
27
*
28
* @param pluginDescriptor plugin metadata
29
* @param session Maven session
30
* @param parent parent classloader
31
* @param imports list of package imports to expose
32
* @param filter dependency filter for plugin dependencies
33
* @return configured class realm for plugin
34
* @throws PluginManagerException if realm setup fails
35
*/
36
ClassRealm setupPluginRealm(PluginDescriptor pluginDescriptor, MavenSession session,
37
ClassLoader parent, List<String> imports, DependencyFilter filter) throws PluginManagerException;
38
39
/**
40
* Get configured Mojo instance.
41
*
42
* @param mojoInterface the Mojo interface class
43
* @param session Maven session
44
* @param mojoExecution mojo execution descriptor
45
* @return configured Mojo instance ready for execution
46
* @throws PluginConfigurationException if configuration fails
47
* @throws PluginContainerException if container operations fail
48
*/
49
<T> T getConfiguredMojo(Class<T> mojoInterface, MavenSession session, MojoExecution mojoExecution)
50
throws PluginConfigurationException, PluginContainerException;
51
52
/**
53
* Release Mojo resources.
54
*
55
* @param mojo the mojo instance to release
56
* @param mojoExecution mojo execution descriptor
57
* @param session Maven session
58
*/
59
void releaseMojo(Object mojo, MojoExecution mojoExecution, MavenSession session);
60
61
/**
62
* Extract plugin artifacts for dependency resolution.
63
*
64
* @param plugin the plugin
65
* @param artifact the plugin artifact
66
* @param session Maven session
67
* @return plugin artifact resolution result
68
* @throws PluginResolutionException if resolution fails
69
*/
70
PluginArtifactsResult resolvePluginArtifacts(Plugin plugin, Artifact artifact, MavenSession session)
71
throws PluginResolutionException;
72
}
73
```
74
75
### BuildPluginManager Interface
76
77
Interface for build-time plugin operations including plugin loading and execution.
78
79
```java { .api }
80
public interface BuildPluginManager {
81
/**
82
* Load plugin for execution.
83
*
84
* @param plugin plugin configuration
85
* @param repositories list of plugin repositories
86
* @param session repository system session
87
* @return loaded plugin descriptor
88
* @throws PluginNotFoundException if plugin cannot be found
89
* @throws PluginResolutionException if plugin resolution fails
90
*/
91
PluginDescriptor loadPlugin(Plugin plugin, List<RemoteRepository> repositories,
92
RepositorySystemSession session) throws PluginNotFoundException, PluginResolutionException;
93
94
/**
95
* Execute a Mojo.
96
*
97
* @param session Maven session
98
* @param execution mojo execution configuration
99
* @throws MojoFailureException if mojo execution fails
100
* @throws MojoExecutionException if mojo execution encounters error
101
* @throws PluginConfigurationException if plugin configuration is invalid
102
* @throws PluginManagerException if plugin management fails
103
*/
104
void executeMojo(MavenSession session, MojoExecution execution)
105
throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException;
106
107
/**
108
* Get plugin classloader realm.
109
*
110
* @param session Maven session
111
* @param pluginDescriptor plugin metadata
112
* @return plugin class realm
113
* @throws PluginManagerException if realm access fails
114
*/
115
ClassRealm getPluginRealm(MavenSession session, PluginDescriptor pluginDescriptor) throws PluginManagerException;
116
}
117
```
118
119
**Plugin Management Example:**
120
```java
121
import org.apache.maven.plugin.MavenPluginManager;
122
import org.apache.maven.plugin.BuildPluginManager;
123
import org.apache.maven.plugin.PluginDescriptor;
124
import org.apache.maven.plugin.MojoExecution;
125
126
@Component
127
private MavenPluginManager pluginManager;
128
129
@Component
130
private BuildPluginManager buildPluginManager;
131
132
public void executeCustomPlugin(MavenSession session) throws Exception {
133
// Create plugin reference
134
Plugin plugin = new Plugin();
135
plugin.setGroupId("org.apache.maven.plugins");
136
plugin.setArtifactId("maven-compiler-plugin");
137
plugin.setVersion("3.11.0");
138
139
// Load plugin
140
PluginDescriptor pluginDescriptor = buildPluginManager.loadPlugin(
141
plugin, session.getCurrentProject().getPluginArtifactRepositories(),
142
session.getRepositorySession());
143
144
// Create mojo execution
145
MojoExecution execution = new MojoExecution(pluginDescriptor.getMojo("compile"));
146
execution.setLifecyclePhase("compile");
147
148
// Configure execution
149
Xpp3Dom configuration = new Xpp3Dom("configuration");
150
Xpp3Dom source = new Xpp3Dom("source");
151
source.setValue("17");
152
configuration.addChild(source);
153
Xpp3Dom target = new Xpp3Dom("target");
154
target.setValue("17");
155
configuration.addChild(target);
156
execution.setConfiguration(configuration);
157
158
// Execute mojo
159
buildPluginManager.executeMojo(session, execution);
160
161
System.out.println("Plugin executed successfully: " +
162
pluginDescriptor.getGroupId() + ":" +
163
pluginDescriptor.getArtifactId() + ":" +
164
pluginDescriptor.getVersion());
165
}
166
```
167
168
## Mojo Execution
169
170
### MojoExecution Class
171
172
Represents the execution context and configuration for a single Mojo.
173
174
```java { .api }
175
public class MojoExecution {
176
/**
177
* Create mojo execution for a mojo descriptor.
178
*
179
* @param mojoDescriptor the mojo to execute
180
*/
181
public MojoExecution(MojoDescriptor mojoDescriptor);
182
183
/**
184
* Create mojo execution with execution ID.
185
*
186
* @param mojoDescriptor the mojo to execute
187
* @param executionId unique execution identifier
188
*/
189
public MojoExecution(MojoDescriptor mojoDescriptor, String executionId);
190
191
/**
192
* Create mojo execution with configuration.
193
*
194
* @param mojoDescriptor the mojo to execute
195
* @param configuration mojo configuration
196
*/
197
public MojoExecution(MojoDescriptor mojoDescriptor, PlexusConfiguration configuration);
198
199
// Execution Identity
200
public String getExecutionId();
201
public void setExecutionId(String executionId);
202
203
// Plugin Information
204
public Plugin getPlugin();
205
public void setPlugin(Plugin plugin);
206
207
// Goal Information
208
public String getGoal();
209
public void setGoal(String goal);
210
211
// Lifecycle Information
212
public String getLifecyclePhase();
213
public void setLifecyclePhase(String lifecyclePhase);
214
215
// Mojo Descriptor
216
public MojoDescriptor getMojoDescriptor();
217
public void setMojoDescriptor(MojoDescriptor mojoDescriptor);
218
219
// Configuration
220
public PlexusConfiguration getConfiguration();
221
public void setConfiguration(PlexusConfiguration configuration);
222
223
// Source Location
224
public InputLocation getLocation(Object key);
225
public void setLocation(Object key, InputLocation location);
226
227
// String representation
228
public String toString();
229
public String identify();
230
}
231
```
232
233
**Mojo Execution Example:**
234
```java
235
import org.apache.maven.plugin.MojoExecution;
236
import org.apache.maven.plugin.descriptor.MojoDescriptor;
237
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
238
239
public MojoExecution createCompilerExecution() {
240
// Get mojo descriptor (typically from plugin descriptor)
241
MojoDescriptor compilerMojo = pluginDescriptor.getMojo("compile");
242
243
// Create execution
244
MojoExecution execution = new MojoExecution(compilerMojo, "default-compile");
245
execution.setLifecyclePhase("compile");
246
247
// Configure mojo parameters
248
Xpp3Dom config = new Xpp3Dom("configuration");
249
250
Xpp3Dom source = new Xpp3Dom("source");
251
source.setValue("17");
252
config.addChild(source);
253
254
Xpp3Dom target = new Xpp3Dom("target");
255
target.setValue("17");
256
config.addChild(target);
257
258
Xpp3Dom encoding = new Xpp3Dom("encoding");
259
encoding.setValue("UTF-8");
260
config.addChild(encoding);
261
262
execution.setConfiguration(new XmlPlexusConfiguration(config));
263
264
return execution;
265
}
266
267
// Execute with build plugin manager
268
public void executeCompilation(MavenSession session, MojoExecution execution) throws Exception {
269
try {
270
buildPluginManager.executeMojo(session, execution);
271
System.out.println("Compilation successful");
272
} catch (MojoFailureException e) {
273
System.err.println("Compilation failed: " + e.getMessage());
274
throw e;
275
} catch (MojoExecutionException e) {
276
System.err.println("Compilation error: " + e.getMessage());
277
throw e;
278
}
279
}
280
```
281
282
## Plugin Caching
283
284
### PluginRealmCache Interface
285
286
Caches plugin classloader realms for performance optimization.
287
288
```java { .api }
289
public interface PluginRealmCache {
290
/**
291
* Cache key for plugin realm entries.
292
*/
293
interface Key {
294
// Key implementation details
295
}
296
297
/**
298
* Cached plugin realm record.
299
*/
300
class CacheRecord {
301
public ClassRealm getRealm();
302
public List<Artifact> getArtifacts();
303
public List<ComponentDescriptor<?>> getComponentDescriptors();
304
}
305
306
/**
307
* Get cached plugin realm.
308
*
309
* @param key cache key for the plugin
310
* @return cached realm record or null if not cached
311
*/
312
CacheRecord get(Key key);
313
314
/**
315
* Put plugin realm in cache.
316
*
317
* @param key cache key
318
* @param record realm record to cache
319
* @return previous cached record or null
320
*/
321
CacheRecord put(Key key, CacheRecord record);
322
323
/**
324
* Remove plugin realm from cache.
325
*
326
* @param key cache key
327
* @return removed record or null if not present
328
*/
329
CacheRecord remove(Key key);
330
331
/**
332
* Clear all cached plugin realms.
333
*/
334
void clear();
335
336
/**
337
* Register cache cleanup callback.
338
*
339
* @param record realm record to monitor
340
* @param callback cleanup callback
341
*/
342
void register(MavenProject project, Key key, CacheRecord record, CacheCleanupCallback callback);
343
}
344
```
345
346
### PluginDescriptorCache Interface
347
348
Caches plugin descriptors to avoid repeated parsing and loading.
349
350
```java { .api }
351
public interface PluginDescriptorCache {
352
/**
353
* Cache key for plugin descriptors.
354
*/
355
interface Key {
356
// Key implementation details
357
}
358
359
/**
360
* Get cached plugin descriptor.
361
*
362
* @param key cache key
363
* @return cached plugin descriptor or null if not cached
364
*/
365
PluginDescriptor get(Key key);
366
367
/**
368
* Put plugin descriptor in cache.
369
*
370
* @param key cache key
371
* @param descriptor plugin descriptor to cache
372
* @return previous cached descriptor or null
373
*/
374
PluginDescriptor put(Key key, PluginDescriptor descriptor);
375
376
/**
377
* Remove plugin descriptor from cache.
378
*
379
* @param key cache key
380
* @return removed descriptor or null if not present
381
*/
382
PluginDescriptor remove(Key key);
383
384
/**
385
* Clear all cached plugin descriptors.
386
*/
387
void clear();
388
}
389
```
390
391
### PluginArtifactsCache Interface
392
393
Caches resolved plugin artifact dependencies.
394
395
```java { .api }
396
public interface PluginArtifactsCache {
397
/**
398
* Cache key for plugin artifacts.
399
*/
400
interface Key {
401
// Key implementation details
402
}
403
404
/**
405
* Get cached plugin artifacts.
406
*
407
* @param key cache key
408
* @return cached artifacts or null if not cached
409
*/
410
PluginArtifactsResult get(Key key);
411
412
/**
413
* Put plugin artifacts in cache.
414
*
415
* @param key cache key
416
* @param result artifacts result to cache
417
* @return previous cached result or null
418
*/
419
PluginArtifactsResult put(Key key, PluginArtifactsResult result);
420
421
/**
422
* Remove plugin artifacts from cache.
423
*
424
* @param key cache key
425
* @return removed result or null if not present
426
*/
427
PluginArtifactsResult remove(Key key);
428
429
/**
430
* Clear all cached plugin artifacts.
431
*/
432
void clear();
433
}
434
```
435
436
**Caching Usage Example:**
437
```java
438
import org.apache.maven.plugin.PluginRealmCache;
439
import org.apache.maven.plugin.PluginDescriptorCache;
440
441
@Component
442
private PluginRealmCache realmCache;
443
444
@Component
445
private PluginDescriptorCache descriptorCache;
446
447
public PluginDescriptor getCachedPluginDescriptor(Plugin plugin, RepositorySystemSession session) {
448
// Create cache key (implementation specific)
449
PluginDescriptorCache.Key key = createDescriptorKey(plugin, session);
450
451
// Try cache first
452
PluginDescriptor descriptor = descriptorCache.get(key);
453
if (descriptor != null) {
454
System.out.println("Plugin descriptor found in cache");
455
return descriptor;
456
}
457
458
// Load and cache descriptor
459
try {
460
descriptor = pluginManager.getPluginDescriptor(plugin, repositories, session);
461
descriptorCache.put(key, descriptor);
462
System.out.println("Plugin descriptor loaded and cached");
463
return descriptor;
464
} catch (Exception e) {
465
System.err.println("Failed to load plugin descriptor: " + e.getMessage());
466
throw new RuntimeException(e);
467
}
468
}
469
470
public ClassRealm getCachedPluginRealm(PluginDescriptor descriptor, MavenSession session) {
471
// Create cache key
472
PluginRealmCache.Key key = createRealmKey(descriptor, session);
473
474
// Check cache
475
PluginRealmCache.CacheRecord record = realmCache.get(key);
476
if (record != null) {
477
System.out.println("Plugin realm found in cache");
478
return record.getRealm();
479
}
480
481
// Setup and cache realm
482
try {
483
ClassRealm realm = pluginManager.setupPluginRealm(descriptor, session, null, null, null);
484
485
PluginRealmCache.CacheRecord newRecord = new PluginRealmCache.CacheRecord();
486
// Set record properties...
487
488
realmCache.put(key, newRecord);
489
System.out.println("Plugin realm created and cached");
490
return realm;
491
} catch (Exception e) {
492
System.err.println("Failed to setup plugin realm: " + e.getMessage());
493
throw new RuntimeException(e);
494
}
495
}
496
```
497
498
## Plugin Resolution
499
500
### PluginPrefixResolver Interface
501
502
Resolves plugin prefixes to full plugin coordinates.
503
504
```java { .api }
505
public interface PluginPrefixResolver {
506
/**
507
* Resolve plugin prefix to plugin coordinates.
508
*
509
* @param prefix plugin prefix (e.g., "compiler", "surefire")
510
* @param pluginGroups list of plugin groups to search
511
* @param session repository system session
512
* @return plugin prefix resolution result
513
* @throws PluginPrefixResolutionException if resolution fails
514
*/
515
PluginPrefixResult resolve(String prefix, List<String> pluginGroups,
516
RepositorySystemSession session) throws PluginPrefixResolutionException;
517
}
518
```
519
520
### PluginVersionResolver Interface
521
522
Resolves plugin versions when not explicitly specified.
523
524
```java { .api }
525
public interface PluginVersionResolver {
526
/**
527
* Resolve plugin version.
528
*
529
* @param request plugin version resolution request
530
* @return plugin version resolution result
531
* @throws PluginVersionResolutionException if resolution fails
532
*/
533
PluginVersionResult resolve(PluginVersionRequest request) throws PluginVersionResolutionException;
534
}
535
```
536
537
**Plugin Resolution Example:**
538
```java
539
import org.apache.maven.plugin.prefix.PluginPrefixResolver;
540
import org.apache.maven.plugin.version.PluginVersionResolver;
541
542
@Component
543
private PluginPrefixResolver prefixResolver;
544
545
@Component
546
private PluginVersionResolver versionResolver;
547
548
public Plugin resolvePluginFromPrefix(String prefix, MavenSession session) throws Exception {
549
// Resolve prefix to coordinates
550
List<String> pluginGroups = Arrays.asList(
551
"org.apache.maven.plugins",
552
"org.codehaus.mojo"
553
);
554
555
PluginPrefixResult prefixResult = prefixResolver.resolve(
556
prefix, pluginGroups, session.getRepositorySession());
557
558
// Create plugin with resolved coordinates
559
Plugin plugin = new Plugin();
560
plugin.setGroupId(prefixResult.getGroupId());
561
plugin.setArtifactId(prefixResult.getArtifactId());
562
563
// Resolve version if not specified
564
if (plugin.getVersion() == null) {
565
PluginVersionRequest versionRequest = new DefaultPluginVersionRequest(plugin, session);
566
PluginVersionResult versionResult = versionResolver.resolve(versionRequest);
567
plugin.setVersion(versionResult.getVersion());
568
}
569
570
System.out.println("Resolved plugin: " + plugin.getGroupId() + ":" +
571
plugin.getArtifactId() + ":" + plugin.getVersion() +
572
" from prefix: " + prefix);
573
574
return plugin;
575
}
576
577
// Example usage
578
public void executePluginByPrefix(String prefix, String goal, MavenSession session) throws Exception {
579
// Resolve plugin from prefix
580
Plugin plugin = resolvePluginFromPrefix(prefix, session);
581
582
// Load plugin descriptor
583
PluginDescriptor descriptor = buildPluginManager.loadPlugin(
584
plugin, session.getCurrentProject().getPluginArtifactRepositories(),
585
session.getRepositorySession());
586
587
// Create and execute mojo
588
MojoExecution execution = new MojoExecution(descriptor.getMojo(goal));
589
buildPluginManager.executeMojo(session, execution);
590
}
591
```
592
593
## Types
594
595
```java { .api }
596
public interface PluginDescriptor {
597
String getGroupId();
598
String getArtifactId();
599
String getVersion();
600
String getGoalPrefix();
601
602
List<MojoDescriptor> getMojos();
603
MojoDescriptor getMojo(String goal);
604
605
ClassRealm getClassRealm();
606
void setClassRealm(ClassRealm classRealm);
607
608
List<Artifact> getArtifacts();
609
void setArtifacts(List<Artifact> artifacts);
610
611
List<ComponentDescriptor<?>> getComponents();
612
}
613
614
public interface MojoDescriptor {
615
String getGoal();
616
String getPhase();
617
String getExecutePhase();
618
String getExecuteGoal();
619
String getExecuteLifecycle();
620
621
String getImplementation();
622
String getLanguage();
623
String getComponentType();
624
String getInstantiationStrategy();
625
626
boolean isAggregator();
627
boolean isDirectInvocationOnly();
628
boolean isProjectRequired();
629
boolean isOnlineRequired();
630
boolean isInheritedByDefault();
631
632
List<Parameter> getParameters();
633
Parameter getParameter(String name);
634
635
PluginDescriptor getPluginDescriptor();
636
}
637
638
public interface Parameter {
639
String getName();
640
String getType();
641
boolean isRequired();
642
boolean isEditable();
643
String getDescription();
644
String getExpression();
645
String getDefaultValue();
646
}
647
648
public interface PluginArtifactsResult {
649
List<Artifact> getArtifacts();
650
Map<String, Artifact> getArtifactMap();
651
}
652
653
public interface ClassRealm extends ClassLoader {
654
String getId();
655
ClassWorld getWorld();
656
657
void importFrom(String realmId, String packageName);
658
void importFromParent(String packageName);
659
660
ClassRealm getParentRealm();
661
Collection<ClassRealm> getImportRealms();
662
663
void addURL(URL url);
664
URL[] getURLs();
665
666
void display();
667
}
668
669
public interface CacheCleanupCallback {
670
void cleanup(CacheRecord record);
671
}
672
673
public interface PluginPrefixResult {
674
String getGroupId();
675
String getArtifactId();
676
}
677
678
public interface PluginVersionResult {
679
String getVersion();
680
Repository getRepository();
681
}
682
```