You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by jaxzin <Br...@espn3.com> on 2008/08/02 06:02:00 UTC
Re: Adding project dependencies and generated classes to classpath
of my plugin
So after trying out more complex scenarios with my first solution (like
calling Class.forName from a class that was injected by the Plexus
container) it turned out it wasn't a complete solution. So learned alot
more about Plexus and the ClassWorlds framework and I ended up discovering a
much more elegant solution. I created a custom ComponentConfigurator that
adds my project dependencies to the ClassRealm for the mojo.
Here's my ComponentConfigurator:
---------------------------------------------------
package com.example;
import org.codehaus.classworlds.ClassRealm;
import
org.codehaus.plexus.component.configurator.AbstractComponentConfigurator;
import
org.codehaus.plexus.component.configurator.ComponentConfigurationException;
import org.codehaus.plexus.component.configurator.ConfigurationListener;
import
org.codehaus.plexus.component.configurator.converters.composite.ObjectWithFieldsConverter;
import
org.codehaus.plexus.component.configurator.converters.special.ClassRealmConverter;
import
org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
import
org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* A custom ComponentConfigurator which adds the project's runtime classpath
elements
* to the
*
* @author mailto:Brian.R.Jackson@espn3.com Brian Jackson
* @since Aug 1, 2008 3:04:17 PM
*
* @plexus.component
role="org.codehaus.plexus.component.configurator.ComponentConfigurator"
* role-hint="include-project-dependencies"
* @plexus.requirement
role="org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup"
* role-hint="default"
*/
public class IncludeProjectDependenciesComponentConfigurator extends
AbstractComponentConfigurator {
private static final Logger LOGGER =
LoggerFactory.getLogger(IncludeProjectDependenciesComponentConfigurator.class);
public void configureComponent( Object component, PlexusConfiguration
configuration,
ExpressionEvaluator expressionEvaluator,
ClassRealm containerRealm,
ConfigurationListener listener )
throws ComponentConfigurationException {
addProjectDependenciesToClassRealm(expressionEvaluator,
containerRealm);
converterLookup.registerConverter( new ClassRealmConverter(
containerRealm ) );
ObjectWithFieldsConverter converter = new
ObjectWithFieldsConverter();
converter.processConfiguration( converterLookup, component,
containerRealm.getClassLoader(), configuration,
expressionEvaluator, listener );
}
private void addProjectDependenciesToClassRealm(ExpressionEvaluator
expressionEvaluator, ClassRealm containerRealm) throws
ComponentConfigurationException {
List<String> runtimeClasspathElements;
try {
//noinspection unchecked
runtimeClasspathElements = (List<String>)
expressionEvaluator.evaluate("${project.runtimeClasspathElements}");
} catch (ExpressionEvaluationException e) {
throw new ComponentConfigurationException("There was a problem
evaluating: ${project.runtimeClasspathElements}", e);
}
// Add the project dependencies to the ClassRealm
final URL[] urls = buildURLs(runtimeClasspathElements);
for (URL url : urls) {
containerRealm.addConstituent(url);
}
}
private URL[] buildURLs(List<String> runtimeClasspathElements) throws
ComponentConfigurationException {
// Add the projects classes and dependencies
List<URL> urls = new
ArrayList<URL>(runtimeClasspathElements.size());
for (String element : runtimeClasspathElements) {
try {
final URL url = new File(element).toURI().toURL();
urls.add(url);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Added to project class loader: " + url);
}
} catch (MalformedURLException e) {
throw new ComponentConfigurationException("Unable to access
project dependency: " + element, e);
}
}
// Add the plugin's dependencies (so Trove stuff works if Trove
isn't on
return urls.toArray(new URL[urls.size()]);
}
}
----------------------------------------------------------------------
And then to use it in my mojo, I needed to add the following plugin to my
pom.xml so the plexus doclets are used to create a components.xml:
---------------------------------------
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
---------------------------------------
And the last step is to add the following doclet to my Mojo:
@configurator include-project-dependencies
----------------------------------------
So that ended up being a much more elegant solution and any ClassLoader
issues I had were resolved.
--
View this message in context: http://www.nabble.com/Adding-project-dependencies-and-generated-classes-to-classpath-of-my-plugin-tp18624435p18785907.html
Sent from the Maven - Users mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org