[jsword-devel] NullPointer in JSword, at runtime using the maven dependency
DM Smith
dmsmith at crosswire.org
Thu Apr 22 03:33:18 MST 2010
On Apr 21, 2010, at 6:54 PM, Chris Burrell wrote:
> After some hunting and some testing, I found that this is in fact not anything to do with jsword, common or the TyndaleStep code.
>
> Maven internally uses different Class realms, presumably to separate the different contexts in which it runs things. As a result it deals with its own ClassLoaders. Apparently Plexus which it relies on uses File.toURL() instead of File.toURI().toURL() when populating the class realms.
>
> This is documented here: http://jira.codehaus.org/browse/MNG-3607 and apparently gets fixed in maven 3 alpha!
Whew! That makes me feel better. BTW, a significant Java difference between a URI and an URL: A URI does not have to describe something that exists but a URL always resolves it's target, going out on the network/filesystem to ensure that the object exists. Thus, using URIs is much faster.
>
> Do you still want me to raise a defect? The easiest workaround (but affects most maven developers) is to change the settings.xml to specify the local repository as c:\docume~1\username\... The other work around would be to do a nasty url.getExternalForm().replace("%20", " "), but then all the resources across the whole of JSword would take a hit, for no other reason than it doesn't work during dev.
If the defect is expressed in JSwords poms and can be fixed then then yes, with a patch to those pom or xml files. Otherwise, it is just a learning experience for maven users on Windows. But, we may want to open an issue, describe the work around and resolve it as "Won't Fix."
I don't think that we want to have a bug work around in the code when we don't have to.
>
> Chris
>
>
> On 20 April 2010 01:25, DM Smith <dmsmith at crosswire.org> wrote:
>
> On Apr 18, 2010, at 12:31 PM, Chris Burrell wrote:
>
>> Ok, so here's an answer to this weird problem... As DM said, it seemed to be a classpath issue, but then since NetUtils is being executed, at least part of the jar file is being found. And the maven output shows it's on the path.
>>
>> But here's what is happening:
>> - My Maven repository is located on Windows under c:\Documents and Settings\username\.m2
>>
>> The following method in NetUtils returns a null because a URISyntaxException is being caught
>> public static URI toURI(URL url) {
>> try {
>> return new URI(url.toExternalForm());
>> } catch (URISyntaxException e) {
>> return null;
>> }
>> }
>>
>> Now the reason for that is "Illegal character in opaque part at index 22: jar:file:/C:/Documents and"
>>
>> That character is a space character. It seems the toExternalForm() method doesn't like the space. Perhaps because the space should probably be a %20? (haven't tried that).
>
> Hmm. Not sure what the problem is. According to Java 1.5 the proper way to convert a URL to a URI is to call url.toURI(). This is just a wrapper for new URI(url.toString()); In both Java 1.5 and Java 1.4.2, url.toString() is just a wrapper to url.toExternalForm(), and url.toExternalForm() merely calls handler.toExternalForm(this).
>
> The documentation clearly states that some URLs cannot be encoded via toExternalForm. And it seems that we've clearly hit that.
>
> What frustrates me is that it appears that Java is returning an URL from the class loader that is not URL encoded.
>
> From the RFC for URIs it says the proper way to do URL encoding is to construct an URL from parts. Each part can be encoded.
>
>>
>> My quick workaround is to do as suggested on this post: http://www.mail-archive.com/users@maven.apache.org/msg84160.html and rewrite my Maven settings.xml so that the local repository is at c:\Docume~1\username\.m2
>>
>> A better solution would be to do the following to test whether we can pass a URL encoded form to the URL object above (I assume that will have quite a lot of impact so we'd need to test this quite a bit)
>>
>> Also perhaps some logging of the exception would be nice.
>> I assume people will have the same problem if they happen to install Bible Desktop at c:\bible desktop\ because of the space (but again haven't tested)
>>
>> Happy to try and create a patch for it, or not.
>
> Yes please. Also create an issue in www.crosswire.org/bugs under JSword and attach your patches to it.
>
> Many thanks.
>
>
>> Cheers
>> Chris :)
>>
>>
>>
>>
>>
>> On 18 April 2010 01:43, DM Smith <dmsmith at crosswire.org> wrote:
>> I'm not to familiar with maven, but I don't think I checked in the latest poms.
>>
>> I'm not clear as to why it would get a ClassDefNotFoundError. That sounds like a class path error.
>>
>> -- DM
>>
>> On Apr 17, 2010, at 1:50 PM, Chris Burrell wrote:
>>
>>> Hi
>>>
>>> I'm trying to get my project to compile/run against the JSword POM. I'm hitting a couple of issues (which might be related)
>>>
>>> 1st: mvn clean install fails to retrieve a dependency, which is not very helpful. However it does seem to build common and JSword properly. I posted a message recently on this, but there was no feedback?
>>>
>>> 2nd, when trying to use it to install some bible versions, I get a ClassDefNotFoundError which is due to a NullPointerException in NetUtil class.
>>>
>>> It seems that we're not forming a proper URL from:
>>> URL index = ResourceUtil.getResource(ReadingsBookDriver.class, "readings.txt"); //$NON-NLS-1$
>>>
>>> I'm not familiar with what the correct behaviour should be. I've checked that JAR that the Maven plugin builds, and readings.txt does indeed exist. Does anyone have any ideas?
>>>
>>> This only happens through Maven when I run my packaged jar. When I run this through Eclipse it seems fine, which sounded to me like it be a dependency issue, but I can't figure our what the problem is...
>>> Any ideas anyone?
>>> Cheers,
>>> Chris
>>>
>>>
>>> Output from Maven:
>>> [DEBUG] Collected project classpath [D:\temp\release_final_test\step-dataloader\target\classes]
>>> [DEBUG] Adding to classpath : file:/D:/temp/release_final_test/step-dataloader/target/classes/
>>> [DEBUG] Adding project dependency artifact: jsword to classpath
>>> [DEBUG] Adding project dependency artifact: log4j to classpath
>>> [DEBUG] Adding project dependency artifact: jsword-common to classpath
>>> [DEBUG] Adding project dependency artifact: commons-codec to classpath
>>> [DEBUG] Adding project dependency artifact: commons-httpclient to classpath
>>> [DEBUG] Adding project dependency artifact: commons-logging to classpath
>>> [DEBUG] Adding project dependency artifact: commons-net to classpath
>>> [DEBUG] Adding project dependency artifact: oro to classpath
>>> [DEBUG] Adding project dependency artifact: javatar to classpath
>>> [DEBUG] Adding project dependency artifact: jdom to classpath
>>> [DEBUG] Adding project dependency artifact: lucene-core to classpath
>>> [DEBUG] Adding project dependency artifact: lucene-snowball to classpath
>>> [DEBUG] Adding project dependency artifact: lucene-smartcn to classpath
>>> [DEBUG] Adding project dependency artifact: lucene-analyzers to classpath
>>> [DEBUG] Adding project dependency artifact: commons-dbutils to classpath
>>> [DEBUG] Adding project dependency artifact: commons-io to classpath
>>> [DEBUG] Adding project dependency artifact: commons-lang to classpath
>>> [DEBUG] Adding project dependency artifact: opencsv to classpath
>>> [DEBUG] Adding project dependency artifact: derbyclient to classpath
>>> [DEBUG] Adding project dependency artifact: derby to classpath
>>> [DEBUG] joining on thread Thread[com.tyndalehouse.step.dataloader.Dataloader.main(),5,com.tyndalehouse.step.dataloader.Dataloader]
>>> [DEBUG] Setting accessibility to true in order to invoke main().
>>> Using connection string: jdbc:derby:C:\Documents and Settings\CJBurrell/TyndaleStep/StepDB;create=true
>>> 0 [com.tyndalehouse.step.dataloader.Dataloader.main()] WARN com.tyndalehouse.step.dataloader.loaders.JSwordModuleInstaller - Creating new installer for JSw
>>> ord
>>> Currently hardcoded installer host to:www.crosswire.org
>>> Currently hardcoded property names for step
>>> Setting to (www.crosswire.org via 10.154.1.44:8080)
>>> Setting package and catalog directories
>>> 641 [com.tyndalehouse.step.dataloader.Dataloader.main()] INFO com.tyndalehouse.step.dataloader.loaders.JSwordModuleInstaller - installing ESV
>>> [INFO] ------------------------------------------------------------------------
>>> [ERROR] BUILD ERROR
>>> [INFO] ------------------------------------------------------------------------
>>> [INFO] An exception occured while executing the Java class. null
>>>
>>> [INFO] ------------------------------------------------------------------------
>>> [DEBUG] Trace
>>> org.apache.maven.lifecycle.LifecycleExecutionException: An exception occured while executing the Java class. null
>>> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:719)
>>> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:569)
>>> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:539)
>>> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
>>> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
>>> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
>>> at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
>>> at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
>>> at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
>>> at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>> at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
>>> at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
>>> at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
>>> at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
>>> Caused by: org.apache.maven.plugin.MojoExecutionException: An exception occured while executing the Java class. null
>>> at org.codehaus.mojo.exec.ExecJavaMojo.execute(ExecJavaMojo.java:338)
>>> at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
>>> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
>>> ... 17 more
>>> Caused by: java.lang.reflect.InvocationTargetException
>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>> at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:283)
>>> at java.lang.Thread.run(Thread.java:619)
>>> Caused by: java.lang.ExceptionInInitializerError
>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>> at org.crosswire.jsword.book.Books.autoRegister(Books.java:426)
>>> at org.crosswire.jsword.book.Books.initialize(Books.java:407)
>>> at org.crosswire.jsword.book.Books.<init>(Books.java:59)
>>> at org.crosswire.jsword.book.Books.<clinit>(Books.java:473)
>>> at com.tyndalehouse.step.dataloader.loaders.JSwordModuleInstaller.installBible(JSwordModuleInstaller.java:46)
>>> at com.tyndalehouse.step.dataloader.loaders.JSwordModuleInstaller.installDefaultModules(JSwordModuleInstaller.java:33)
>>> at com.tyndalehouse.step.dataloader.Dataloader.main(Dataloader.java:33)
>>> ... 6 more
>>> Caused by: java.lang.NullPointerException
>>> at org.crosswire.common.util.NetUtil.getInputStream(NetUtil.java:415)
>>> at org.crosswire.common.util.NetUtil.listByIndexFile(NetUtil.java:544)
>>> at org.crosswire.jsword.book.readings.ReadingsBookDriver.getInstalledReadingsSets(ReadingsBookDriver.java:91)
>>> at org.crosswire.jsword.book.readings.ReadingsBookDriver.<init>(ReadingsBookDriver.java:50)
>>> at org.crosswire.jsword.book.readings.ReadingsBookDriver.<clinit>(ReadingsBookDriver.java:119)
>>>
>>>
>>> my dependencies:
>>> <dependency>
>>> <groupId>org.crosswire</groupId>
>>> <artifactId>jsword</artifactId>
>>> <version>1.6.1-SNAPSHOT</version>
>>> </dependency>
>>>
>>> My plugin to run the jar:
>>>
>>> <plugins>
>>> <plugin>
>>> <groupId>org.codehaus.mojo</groupId>
>>> <artifactId>exec-maven-plugin</artifactId>
>>> <configuration>
>>> <mainClass>com.tyndalehouse.step.dataloader.Dataloader</mainClass>
>>> <systemProperties>
>>> <systemProperty>
>>> <key>db.location</key>
>>> <value>${db.directory}</value>
>>> </systemProperty>
>>> <systemProperty>
>>> <key>step.http.proxy</key>
>>> <value>${step.http.proxy}</value>
>>> </systemProperty>
>>> <systemProperty>
>>> <key>step.http.port</key>
>>> <value>${step.http.port}</value>
>>> </systemProperty>
>>> </systemProperties>
>>> <classpathScope>runtime</classpathScope>
>>> </configuration>
>>> </plugin>
>>>
>>>
>>> _______________________________________________
>>> jsword-devel mailing list
>>> jsword-devel at crosswire.org
>>> http://www.crosswire.org/mailman/listinfo/jsword-devel
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.crosswire.org/pipermail/jsword-devel/attachments/20100422/4540efee/attachment-0001.html>
More information about the jsword-devel
mailing list