Well, you're right - is it due to spaces in the path... but I still think
the problem is in __exctractStringFromURL(). The problem is this method
trims the 'path' component of a URL and later it is treated as if it were a
file path. One of the main differences between a URL's 'path' component and
a 'file path' is that URLs escape spaces as %20, while 'file paths' leave
them as spaces.
I've attached a unit test demonstrating the problem (and a potential
solution) and I've reported the bug to Apple (6841776).
Out of interest Henrique - was this the cause of the problem with spaces
that you identified? What was your proposed solution?

(as an aside - wouldn't it be nice if this were an open source project and
we could see each other's bug reports and submit patches? - one can only
dream)

Cheers,

Jake

On Thu, Apr 30, 2009 at 9:54 AM, Jake MacMullin <jmacmul...@gmail.com>wrote:

> Henrique,
> Of course - I remember encountering this before. I wonder if it is the root
> cause of the problem I was encountering (or if the error I think I found in 
> __exctractStringFromURL()
> is the reason spaces cause problems).
>
> Interestingly, I can get my unit tests to work on Windows by manually
> calling the code that is meant to be called in NSBundle's initialisation.
> For example, the following works:
>
> NSBundle._bundleWithPathShouldCreateIsJar("C:\\Documents and
> Settings\\username\\.m2\\repository\\com\\webobjects\\JavaEOAccess\\5.4.2\\JavaEOAccess-5.4.2.jar",
> true, true);
>
> That is, after I've done this with all the .jars I need,
> EOModelGroup.defaultGroup() no longer throws an exception.
>
> Out of interest, I'm going to move my .jars so there are no spaces in the
> path and see if this also solves the problem.
>
> Thanks,
>
> Jake
>
> On Wed, Apr 29, 2009 at 11:09 PM, Henrique Prange <hpra...@gmail.com>wrote:
>
>> Hi Jake,
>>
>> The problem is caused by white spaces in the path. Do not put WO
>> libraries/projects on "C:\Documents and Settings".
>>
>> I've reported the bug 5941664 on 16-May-2008 with a simple suggestion
>> about how to solve the problem. The issue is still open as you can see in
>> the attached screenshot.
>>
>> Cheers,
>>
>> Henrique
>>
>> PS.: WO applications deployed as WAR on Windows only work if the servlet
>> container is installed in a path WITHOUT white spaces. Otherwise, you'll
>> have a similar exception while starting the container.
>>
>> Jake MacMullin wrote:
>>
>>> Today I finally decided to see if I could find out why our suite of EO
>>> unit tests kept failing on Windows while passing on Mac OS X and Linux
>>> (don't ask me why I'm using Windows).
>>>
>>> All our EO unit tests have a common parent class that has a @BeforeClass
>>> method that makes sure the EOModel has been loaded (because in some
>>> circumstances - such as when being run as part of a build, the model wasn't
>>> loaded when our unit tests needed it). This method attempts to load the
>>> model if it hasn't been loaded by first calling:
>>>
>>> EOModelGroup.defaultGroup().modelNamed("BLAH");
>>>
>>> to see if it has been loaded and then manually loads the group if it
>>> isn't there. The problem was that on Windows EOModelGroup.defaultGroup() was
>>> throwing an exception:
>>>
>>> java.lang.IllegalArgumentException: Attempt to insert null into an
>>> com.webobjects.foundation.NSMutableArray.
>>> at
>>> com.webobjects.foundation.NSMutableArray.addObject(NSMutableArray.java:239)
>>> at
>>> com.webobjects.eoaccess.EOModelGroup.modelGroupForLoadedBundles(EOModelGroup.java:700)
>>> at
>>> com.webobjects.eoaccess.EOModelGroup.globalModelGroup(EOModelGroup.java:306)
>>> at
>>> com.webobjects.eoaccess.EOModelGroup.defaultGroup(EOModelGroup.java:333)
>>> at
>>> com.bbc.fmtj.cps.enterprise.eo.CPSEnterpriseTestCase.loadModel(CPSEnterpriseTestCase.java:283)
>>>
>>> The 'attempt to insert null' was happening because the
>>> 'modelGroupForLoadedBundles()' method tries to make a list of all the loaded
>>> bundles by first adding the 'NSBundle.mainBundle()' to a list and then
>>> adding all of the 'NSBundle.frameworkBundles()'. The problem is that when
>>> running a unit test on Windows NSBundle.mainBundle() returns null and
>>> 'modelGroupForLoadedBundles()' doesn't bother to check for null before
>>> adding the 'main bundle' to the list of 'loaded bundles'.
>>>
>>> So - why does NSBundle.mainBundle() return null on Windows but not on OS
>>> X? - Good question! I don't pretend to understand the mystery that is
>>> NSBundle, but here's what I think is happening.
>>>
>>> NSBundle has a bunch of static initialisation code that runs when the
>>> NSBundle class is loaded. This initialisation code first tries to load
>>> (old-style .framework I assume) 'bundles' from a directory specified by the
>>> 'webobjects.user.dir' property. If this property has not been set, it then
>>> looks in the current application's directory. If it is unable to load any
>>> 'bundles' from these locations it then asks the Java ClassLoader for a list
>>> of URLs to all the Info.plist files found inside of any .jars that are on
>>> the classpath.
>>>
>>> Now I haven't 'installed' WebObjects on my Windows box (this seems like
>>> an out-dated concept to me - I should just be able to reference the .jars)
>>> so it is this final method of 'bundle loading' that I'm relying on. The
>>> problem is - it is broken on non-unix platforms.
>>>
>>> Once NSBundle has got a list of URLs to all the Info.plist files it tries
>>> to turn this in to a list of paths to the .jar files containing the
>>> Info.plist files.
>>>
>>> For example, it wants to turn this:
>>>
>>> jar:file:/C:/Documents%20and%20Settings/.../JavaEOAccess-5.4.2.jar!/Resources/Info.plist
>>>
>>> in to this:
>>> C:\Documents%20and%20Settings\...\JavaEOAccess-5.4.2.jar
>>>
>>> The problem is that the method that tries to do this
>>> (__exctractStringFromURL) isn't quite right. The current implementation
>>> returns a String like this:
>>> /C:/Documents%20and%20Settings/.../JavaEOAccess-5.4.2.jar (note the
>>> leading slash and that the slashes are the wrong kind)
>>>
>>> Later on in the initialisation, NSBundle tries to 'normalise' this path
>>> before attempting to load the bundle from the path. When the
>>> 'NormalizeExistingBundlePath()' method is passed the malformed file path, it
>>> attempts to create a new File object - using the malformed file path and as
>>> a result the 'normalised' path is null.
>>>
>>> Finally, NSBundle tries to load the actual bundle from the given path and
>>> obviously fails to load anything from a null path. Hence no 'bundles' are
>>> loaded at all - which begs the question - how does WebObjects even work on
>>> Windows at all if NSBundle isn't working? (and I don't know the answer to
>>> that question).
>>>
>>> Fixing this should be simple. __exctractStringFromURL() needs to be
>>> re-written to return a proper (platform appropriate) file path (perhaps by
>>> creating a URI using the trimmed path component of the original jar: URL and
>>> then creating a File using this URI and asking it for its getPath()).
>>>
>>> In the meantime, I think I can work around this problem in my code by
>>> calling NSBundle._bundleWithPathShouldCreateIsJar() myself to load all of
>>> the bundles that NSBundle's initialisation code should've loaded anyway -
>>> and then manually set the 'main bundle' by calling
>>> NSBundle._setMainBundle().
>>>
>>> So, now I've gotten to the bottom of this - I have two questions:
>>>
>>> 1. Can anyone explain why WebObjects works on Windows when I deploy a
>>> .WAR containing all the libraries as .jars given that NSBundle seems broken
>>> on Windows?
>>>
>>> 2. Shall I bother submitting a bug report via Radar (given that Mike
>>> fixed the last bug I found before I'd managed to finish writing the bug
>>> report)?
>>>
>>> Thanks,
>>>
>>> Jake
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>>  _______________________________________________
>>> Do not post admin requests to the list. They will be ignored.
>>> Webobjects-dev mailing list      (Webobjects-dev@lists.apple.com)
>>> Help/Unsubscribe/Update your Subscription:
>>> http://lists.apple.com/mailman/options/webobjects-dev/hprange%40gmail.com
>>>
>>> This email sent to hpra...@gmail.com
>>>
>>
>>  _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Webobjects-dev mailing list      (Webobjects-dev@lists.apple.com)
>> Help/Unsubscribe/Update your Subscription:
>>
>> http://lists.apple.com/mailman/options/webobjects-dev/jmacmullin%40gmail.com
>>
>> This email sent to jmacmul...@gmail.com
>>
>
>

Attachment: TestNSBundle.java
Description: Binary data

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      (Webobjects-dev@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to