When an mp3 resource is played with AudioClip.play on mac, and the resource is located in a JAR, a crash may occur.
Example snippet:
```
String source = MainApp.class.getResource(audioFile).toExternalForm();
AudioClip clip = new AudioClip(source);
clip.play();
```
The root cause for this seems to be a wrong object being passed in the native layer.
In its constructor,
`com/sun/media/jfxmediaimpl/platform/osx/OSXMediaPlayer.java`
will invoke
`osxCreatePlayer(mediaLocator, mediaLocator.getContentType(),
mediaLocator.getContentLength());`
which is defined as
`private native void osxCreatePlayer(Locator locator, String contentType, long sizeHint)`
Hence, a Locator instance is passed to the native peer (at OSXMediaPlayer.mm) where it is used in
`JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxCreatePlayer
(JNIEnv *env, jobject playerObject, jobject jLocator, jstring jContentType, jlong jSizeHint)`
That jLocator object is used inside the function for doing Locator-related work indeed, but in case of a jar or jrt scheme, it is also passed to `CJavaInputStreamCallbacks->Init` via
```
CJavaInputStreamCallbacks *callbacks = new (nothrow) CJavaInputStreamCallbacks();
if (!callbacks->Init(env, jLocator)) {
```
The problem is that the latter expects a `ConnectionHolder` and not a `Locator`, as can be seen from
JavaInputStreamCallbacks.cpp:
`bool CJavaInputStreamCallbacks::Init(JNIEnv *env, jobject jConnectionHolder)`
The Init method sets the methodIDs that will be invoked when needed, and it calculates them using the ConnectionHolder class, e.g.:
`jclass klass = env->FindClass("com/sun/media/jfxmedia/locator/ConnectionHolder");`
m_ReadNextBlockMID = env->GetMethodID(klass, "readNextBlock", "()I");`
But when those methods are invoked, the Locator object from the OSXMediaPlayer is used instead of the ConnectionHolder that belongs to the Locator.
Example snippet:
```
String source = MainApp.class.getResource(audioFile).toExternalForm();
AudioClip clip = new AudioClip(source);
clip.play();
```
The root cause for this seems to be a wrong object being passed in the native layer.
In its constructor,
`com/sun/media/jfxmediaimpl/platform/osx/OSXMediaPlayer.java`
will invoke
`osxCreatePlayer(mediaLocator, mediaLocator.getContentType(),
mediaLocator.getContentLength());`
which is defined as
`private native void osxCreatePlayer(Locator locator, String contentType, long sizeHint)`
Hence, a Locator instance is passed to the native peer (at OSXMediaPlayer.mm) where it is used in
`JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxCreatePlayer
(JNIEnv *env, jobject playerObject, jobject jLocator, jstring jContentType, jlong jSizeHint)`
That jLocator object is used inside the function for doing Locator-related work indeed, but in case of a jar or jrt scheme, it is also passed to `CJavaInputStreamCallbacks->Init` via
```
CJavaInputStreamCallbacks *callbacks = new (nothrow) CJavaInputStreamCallbacks();
if (!callbacks->Init(env, jLocator)) {
```
The problem is that the latter expects a `ConnectionHolder` and not a `Locator`, as can be seen from
JavaInputStreamCallbacks.cpp:
`bool CJavaInputStreamCallbacks::Init(JNIEnv *env, jobject jConnectionHolder)`
The Init method sets the methodIDs that will be invoked when needed, and it calculates them using the ConnectionHolder class, e.g.:
`jclass klass = env->FindClass("com/sun/media/jfxmedia/locator/ConnectionHolder");`
m_ReadNextBlockMID = env->GetMethodID(klass, "readNextBlock", "()I");`
But when those methods are invoked, the Locator object from the OSXMediaPlayer is used instead of the ConnectionHolder that belongs to the Locator.