You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by James CE Johnson <jc...@tragus.org> on 2007/04/03 22:53:44 UTC

Classloader issue?

I'm writting a MoJo that uses a utility Iwhich, in turn, uses Spring. When I
invoke the utility (with the correct classpath) from the command line
everything works fine. When I invoke the MoJo from Eclipse everything still
works fine. However, when I invoke the MoJo from mvn it tells me:

org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected
exception parsing XML document from class path resource
[com/myco/foo/util/myUtility/engine.xml]; nested exception is
java.lang.IllegalArgumentException: Class
[org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler] does
not implement the NamespaceHandler interface
Caused by: java.lang.IllegalArgumentException: Class
[org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler] does
not implement the NamespaceHandler interface

A capture of the mvn invocation is at http://rafb.net/p/fOEW5I52.html

It smells like a classloader issue but I'm too new to m2 to know which way
to jump. Any ideas?

Thanks,
James

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Classloader issue? -- Solved

Posted by James CE Johnson <jc...@tragus.org>.
> Problem Solved!
>
> It was, of course, a classloader issue. To solve the problem I created my
> own URLClassLoader instance and gave it the URLs in of my MoJo's
> classloader. Then it was a simple matter to load and instantiate my
> utility class from there.
>
> Because I also need access to the project's classpath I also used
> ${project.runtimeClasspathElements} to import that list.
>
> The relevant solution bits are shown at: http://rafb.net/p/TmK9TL26.html

rafb.net is a short-term paste... Here are those relevant bits in case
somebody needs them in the future:


public class GenerateSqlMojo extends AbstractMojo
{
    ...

    /**
     * The classpath elements of the project.
     * We need this so that we can get the JDBC driver for the project.
     *
     * @parameter expression="${project.runtimeClasspathElements}"
     * @required
     * @readonly
     */
    private List<String> classpathElements;

    public void execute() throws MojoExecutionException
    {
        final URL[] urls = buildUrls();
        final URLClassLoader cl =
              new URLClassLoader(urls, ClassLoader.getSystemClassLoader());
        Thread.currentThread().setContextClassLoader(cl);

        final Class clazz =
                    cl.loadClass(UtilityExecutor.class.getName());
        final Constructor ctor =
                    clazz.getConstructor(new Class[] { String.class,
                                                       String.class });
        ctor.newInstance(new Object[] { inputDirectory, outputPrefix });
    }

    /**
     * Combine the MoJo URLS with the project's classpath elements.
     * We need the classpath elements because the JDBC driver will be
     * specified there.
     *
     * @return
     * @throws MalformedURLException
     */
    private URL[] buildUrls() throws MalformedURLException
    {
        final URL[] mojoUrls =
                    ((URLClassLoader) getClass().getClassLoader()).getURLs();
        final URL[] urls =
                    new URL[mojoUrls.length + classpathElements.size()];
        int ndx = 0;
        for (final URL url : mojoUrls) { urls[ndx++] = url; }
        for (final String cpe : classpathElements) {
                     urls[ndx++] = new URL("file:/" + cpe); }
        return urls;
    }
}


UtilityExecutor is a simple wrapper to execute my utility's main class:

    public UtilityExecutor(final String inputDirectory,
                           final String outputDirectory)
    {
            final MyUtility main = new MyUtility();
            main.setSaveOnlyMode(true);
            main.setSaveTarget(outputDirectory);
            main.execute(new String[] { inputDirectory });
    }

>
> Thanks for the pointers Jerome. I would still be beating my head on the
> desk without your help!
>
>> On 4/4/07, James CE Johnson <jc...@tragus.org> wrote:
>>> Hi Jerome,
>>>
>>> My latest nohup.out is http://rafb.net/p/seMDUu17.html. I've dumped the
>>> classloader of my app as well as the system classloader. It appears
>>> that I have a RealmClassloader loading my classes and it has everything
>>> it needs.
>>>
>>> However, http://rafb.net/p/qC12GT63.html captures my execution from
>>> within Eclipse. Here we see that all of the dependencies are in the
>>> system classloader.
>>>
>>> Perhaps Spring is looking to the (mostly empty) system classloader in
>>> the case where it fails?
>>>
>>> Any insights would be appreciated.
>>
>> In the xfire maven plugin, i've had to override the class loader,
>> otherwise Spring would not find the appropriate classes/resources. See
>>
>> http://svn.codehaus.org/mojo/trunk/mojo/mojo-sandbox/xfire-maven-plugin/src/main/java/org/codehaus/mojo/xfire/WsdlgenMojo.java
>>
>> I would guess that you need to do something similar in your plugin.
>>
>> Cheers,
>>
>> J

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Classloader issue? -- Solved

Posted by James CE Johnson <jc...@tragus.org>.
Problem Solved!

It was, of course, a classloader issue. To solve the problem I created my
own URLClassLoader instance and gave it the URLs in of my MoJo's
classloader. Then it was a simple matter to load and instantiate my utility
class from there.

Because I also need access to the project's classpath I also used
${project.runtimeClasspathElements} to import that list.

The relevant solution bits are shown at: http://rafb.net/p/TmK9TL26.html

Thanks for the pointers Jerome. I would still be beating my head on the desk
without your help!

> On 4/4/07, James CE Johnson <jc...@tragus.org> wrote:
>> Hi Jerome,
>>
>> My latest nohup.out is http://rafb.net/p/seMDUu17.html. I've dumped the
>> classloader of my app as well as the system classloader. It appears that
>> I have a RealmClassloader loading my classes and it has everything it
>> needs.
>>
>> However, http://rafb.net/p/qC12GT63.html captures my execution from
>> within Eclipse. Here we see that all of the dependencies are in the
>> system classloader.
>>
>> Perhaps Spring is looking to the (mostly empty) system classloader in
>> the case where it fails?
>>
>> Any insights would be appreciated.
>
> In the xfire maven plugin, i've had to override the class loader,
> otherwise Spring would not find the appropriate classes/resources. See
>
> http://svn.codehaus.org/mojo/trunk/mojo/mojo-sandbox/xfire-maven-plugin/src/main/java/org/codehaus/mojo/xfire/WsdlgenMojo.java
>
> I would guess that you need to do something similar in your plugin.
>
> Cheers,
>
> J

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Classloader issue?

Posted by Jerome Lacoste <je...@gmail.com>.
On 4/4/07, James CE Johnson <jc...@tragus.org> wrote:
> Hi Jerome,
>
> My latest nohup.out is http://rafb.net/p/seMDUu17.html. I've dumped the
> classloader of my app as well as the system classloader. It appears that I
> have a RealmClassloader loading my classes and it has everything it needs.
>
> However, http://rafb.net/p/qC12GT63.html captures my execution from within
> Eclipse. Here we see that all of the dependencies are in the system
> classloader.
>
> Perhaps Spring is looking to the (mostly empty) system classloader in the
> case where it fails?
>
> Any insights would be appreciated.

In the xfire maven plugin, i've had to override the class loader,
otherwise Spring would not find the appropriate classes/resources. See

http://svn.codehaus.org/mojo/trunk/mojo/mojo-sandbox/xfire-maven-plugin/src/main/java/org/codehaus/mojo/xfire/WsdlgenMojo.java

I would guess that you need to do something similar in your plugin.

Cheers,

J

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Classloader issue?

Posted by James CE Johnson <jc...@tragus.org>.
Hi Jerome,

My latest nohup.out is http://rafb.net/p/seMDUu17.html. I've dumped the
classloader of my app as well as the system classloader. It appears that I
have a RealmClassloader loading my classes and it has everything it needs.

However, http://rafb.net/p/qC12GT63.html captures my execution from within
Eclipse. Here we see that all of the dependencies are in the system
classloader.

Perhaps Spring is looking to the (mostly empty) system classloader in the
case where it fails?

Any insights would be appreciated.

Thanks!
James


> On 4/3/07, James CE Johnson <jc...@tragus.org> wrote:
>> I'm writting a MoJo that uses a utility Iwhich, in turn, uses Spring.
>> When I invoke the utility (with the correct classpath) from the command
>> line everything works fine. When I invoke the MoJo from Eclipse
>> everything still works fine. However, when I invoke the MoJo from mvn it
>> tells me:
>>
>> org.springframework.beans.factory.BeanDefinitionStoreException:
>> Unexpected exception parsing XML document from class path resource
>> [com/myco/foo/util/myUtility/engine.xml]; nested exception is
>> java.lang.IllegalArgumentException: Class
>> [org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler]
>> does not implement the NamespaceHandler interface
>> Caused by: java.lang.IllegalArgumentException: Class
>> [org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler]
>> does not implement the NamespaceHandler interface
>>
>> A capture of the mvn invocation is at http://rafb.net/p/fOEW5I52.html
>>
>> It smells like a classloader issue but I'm too new to m2 to know which
>> way to jump. Any ideas?
>
> Sounds like a classpath issue. If you can, try to see what classpath the
> following code sees:
>
> 	at com.myco.foo.util.myUtility.ContextLoader.load(ContextLoader.java:14)
> at com.myco.foo.util.myUtility.Main.execute(Main.java:47)
>
> You may need to override the classpath given by maven to achieve your
> needs.
>
> See also http://forum.springframework.org/showthread.php?t=35232
>
> J
>
> --------------------------------------------------------------------- To
> unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Classloader issue?

Posted by Jerome Lacoste <je...@gmail.com>.
On 4/3/07, James CE Johnson <jc...@tragus.org> wrote:
> I'm writting a MoJo that uses a utility Iwhich, in turn, uses Spring. When I
> invoke the utility (with the correct classpath) from the command line
> everything works fine. When I invoke the MoJo from Eclipse everything still
> works fine. However, when I invoke the MoJo from mvn it tells me:
>
> org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected
> exception parsing XML document from class path resource
> [com/myco/foo/util/myUtility/engine.xml]; nested exception is
> java.lang.IllegalArgumentException: Class
> [org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler] does
> not implement the NamespaceHandler interface
> Caused by: java.lang.IllegalArgumentException: Class
> [org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler] does
> not implement the NamespaceHandler interface
>
> A capture of the mvn invocation is at http://rafb.net/p/fOEW5I52.html
>
> It smells like a classloader issue but I'm too new to m2 to know which way
> to jump. Any ideas?

Sounds like a classpath issue. If you can, try to see what classpath
the following code sees:

	at com.myco.foo.util.myUtility.ContextLoader.load(ContextLoader.java:14)
	at com.myco.foo.util.myUtility.Main.execute(Main.java:47)

You may need to override the classpath given by maven to achieve your needs.

See also http://forum.springframework.org/showthread.php?t=35232

J

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org