Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.lang.ClassCastException with CGBitmapContext #837

Closed
tomfisher opened this issue Mar 9, 2015 · 36 comments
Closed

java.lang.ClassCastException with CGBitmapContext #837

tomfisher opened this issue Mar 9, 2015 · 36 comments
Labels
Milestone

Comments

@tomfisher
Copy link

This happens again in the latest SNAPSHOT, as reported as issue #728

@badlogic badlogic added the bug label Mar 9, 2015
@badlogic badlogic modified the milestone: 1.0 Mar 9, 2015
@badlogic badlogic removed the bug label Mar 9, 2015
@badlogic
Copy link
Contributor

badlogic commented Mar 9, 2015

I can not reproduce the issue, using this sample:

import org.robovm.apple.coregraphics.CGBitmapContext;
import org.robovm.apple.coregraphics.CGBitmapInfo;
import org.robovm.apple.coregraphics.CGColorSpace;
import org.robovm.apple.coregraphics.CGImageAlphaInfo;

public class Sample
{
    public abstract class Context<GC> {
        public void drawInContext(GC context)
        {
            System.out.println("Context::draw");
        }

        public abstract GC gc();
    }

    public class BitmapContext extends Context<CGBitmapContext> {
        CGBitmapContext nativeContext;

        public BitmapContext()
        {
            nativeContext = CGBitmapContext.create(10, 10, 8, 0, CGColorSpace.createDeviceRGB(), new CGBitmapInfo(CGImageAlphaInfo.PremultipliedFirst.value()));
        }

        @Override
        public void drawInContext(CGBitmapContext context) {
            System.out.println("BitmapContext::draw");
        }

        @Override
        public CGBitmapContext gc() {
            return nativeContext;
        }
    }

    public class Client {
        Context bitmapContext;

        public Client() {
            bitmapContext = new BitmapContext();
        }

        public void doSomethings() {
            bitmapContext.drawInContext(bitmapContext.gc());
        }
    }

    public Sample() {
        BitmapContext bitmapContext = new BitmapContext();
        System.out.println("BitmapContext class: " + bitmapContext.getClass().getGenericSuperclass().toString());
        System.out.println("BitmapContext class: " + bitmapContext.gc().getClass().toString());
        new Client().doSomethings();
    }
}

Calling new Sample() in a dummy app delegate didFinishLaunching produces the following output:

BitmapContext class: Sample$Context<org.robovm.apple.coregraphics.CGBitmapContext>
BitmapContext class: class org.robovm.apple.coregraphics.CGBitmapContext
BitmapContext::draw

Which is what we'd expect.

Which version of PlayN are you using? Does it depend on the latest RoboVM snapshot?

@tomfisher
Copy link
Author

I used the version compatible with the RoboVM API of snapshot 20150309 which can be found at https://github.com/tomfisher/playn, and the following code:

    @Override
    public boolean didFinishLaunching(UIApplication app, UIApplicationLaunchOptions launchOpts) {
        window = new UIWindow(UIScreen.getMainScreen().getBounds());
        window.makeKeyAndVisible();
        Game game = new Game.Default(30){
            @Override
            public void init() {
                final CanvasImage image = PlayN.graphics().createImage(200, 200);
                image.canvas().setFillColor(Colors.RED);
                image.canvas().fillRect(0, 0, 200, 200);

                ImageLayer imageLayer = PlayN.graphics().createImageLayer(image);
                imageLayer.addListener(new Pointer.Adapter(){
                    @Override
                    public void onPointerStart(Event event) {
                        PlayN.log().info("This will cause the exception");
                        CanvasImage target = PlayN.graphics().createImage(PlayN.graphics().width(), PlayN.graphics().height());
                        capture(PlayN.graphics().rootLayer(), target.canvas(), 1);
                    }
                });

                PlayN.graphics().rootLayer().add(imageLayer);
            }
        };

        Config config = new RoboPlatform.Config();
        config.orients = UIInterfaceOrientationMask.All;
        RoboPlatform platform = RoboPlatform.register(window, config);
        addStrongRef(platform);
        platform.run(game);
        return true;
    }

    /** The following code is copied from triplay in order to make the case simpler **/
    public static void capture (Layer layer, Canvas canvas, float alpha) {
        if (!layer.visible()) return;
        canvas.save();

        concatTransform(canvas, layer.transform());
        canvas.translate(-layer.originX(), -layer.originY());

        float nalpha = alpha * layer.alpha();
        if (layer instanceof GroupLayer) {
            GroupLayer gl = (GroupLayer)layer;
            for (int ii = 0, ll = gl.size(); ii < ll; ii++) {
                capture(gl.get(ii), canvas, nalpha);
            }

        } else if (layer instanceof ImageLayer) {
            ImageLayer il = (ImageLayer)layer;
            canvas.setAlpha(nalpha);
            canvas.drawImage(il.image(), 0, 0);
        } else if (layer instanceof ImmediateLayer) {
            ImmediateLayer il = (ImmediateLayer)layer;
            il.renderer().render(new CanvasSurface(canvas.setAlpha(nalpha)));
        }

        canvas.restore();
    }

    /** Utility method for capture. */
    protected static AffineTransform toAffine (Transform t) {
        if (t instanceof AffineTransform) return (AffineTransform)t;
        else return new AffineTransform(t.scaleX(), t.scaleY(), t.rotation(), t.tx(), t.ty());
    }

    /** Utility method for capture. */
    protected static void concatTransform (Canvas canvas, AffineTransform at) {
        canvas.transform(at.m00, at.m01, at.m10, at.m11, at.tx, at.ty);
    }

    /** Utility method for capture. */
    protected static void concatTransform (Canvas canvas, Transform t) {
        concatTransform(canvas, toAffine(t));
    }

It worked fine with alpha-02 if the memory serves me right.

@tomfisher
Copy link
Author

Badlogic,

We're blocked to release the iOS product because of this. I want to know whether you have any plan of working on this issue so that we can reschedule our works.

Thanks.

@badlogic
Copy link
Contributor

Sorry, we were super busy with 1.0. I'll try to fix this until monday.

@badlogic
Copy link
Contributor

Would it be possible for you to send an example project that's properly setup? That's help me focus on the issue instead of trying to figure out how to setup PlayN :)

@tomfisher
Copy link
Author

Sure, give me a moment.

@tomfisher
Copy link
Author

I updated to the 1.0.0 version and the bug just happened sometimes such as a build without any cache may work but it came out sometimes even with a clean build.

Please just ignore this at the moment and keep if open for a while. I'll do more test and let you know the result.

@badlogic
Copy link
Contributor

Sounds good. We'll definitely not close this heisenbug :)
On Mar 14, 2015 3:29 PM, "tomfisher" notifications@github.com wrote:

I updated to the 1.0.0 version and the bug just happened sometimes such as
a build without any cache may work but it came out sometimes even with a
clean build.

Please just ignore this at the moment and keep if open for a while. I'll
do more test and let you know the result.


Reply to this email directly or view it on GitHub
#837 (comment).

@tomfisher
Copy link
Author

I found an interesting problem that the bug may be generated during the compiling or linking process.

The code https://github.com/tomfisher/issue837/blob/master/src/org/robovm/cases/issue837/Main.java includes a private method that is never used in the application and contains the application logics and views based on PlayN. If that method is removed out from the code, the image.canvas().drawImage(snap, 0, 0) works fine. If it's kept in the file, the exception ClassCastException will be thrown.

Do you guys have any thought about this?

BTW, I'm still working on this to narrow down the problem, which is really tedious :-(

@tomfisher
Copy link
Author

Sorry, clicked on the wrong button.

@tomfisher tomfisher reopened this Mar 16, 2015
@tomfisher
Copy link
Author

More strange things happened. I put a line code new RoboURLStarter() into the otherRelatedCauseLinkingError method in the above link. All relevant classes are really simple except RoboApp which I am still working on.

public class RoboURLStarter extends URLStarter {

    final private RoboFile file;
    private UIWebView webview;

    public RoboURLStarter() {
        super();
        this.file = null;
    }
    protected void runRecorder(String url) {
        ResultBuilder result = new ResultBuilder() {
            @Override
            public String buildResult(ActionGame game, String back, Parameter parameters) {
                return null;
            }
        };
        final RoboApp recorder = new RoboApp();
        GameCreator creator = new GameCreator() {
            @Override
            public ActionGame createGame() {
                return null;
            }

            @Override
            public String gameName() {
                return Applications.RECORDER;
            }
        };
    }
}

According to the exception, it should be caused by some classes relevant to CGBitmapContext or CGContext such as UIWebView. However, removing the reference to RoboFile will eliminate the cast exception although RoboFile just refers to a few foundation classes:

final public class RoboFile {
    public RoboFile() {
        NSFileManager mrg = NSFileManager.getDefaultManager();
        NSArray<NSURL> dir = mrg.getURLsForDirectory(
                NSSearchPathDirectory.DocumentDirectory,
                NSSearchPathDomainMask.UserDomainMask);
        dir.get(0).getPath();
    }
}

The more strange thing is that removing the instance 'result' of the interface ResultBuilder also eliminates the cast exception, as well as the instance 'creator'.

As usual, the cast exception disappears when removing some classes and then appears again when removing other classes regardless of whether they are relevant to CGContext or even called when running.

I'll carry on isolating the problem from the complicated project and hope the above info could be enough for you to tackle the problem :)

@BlueRiverInteractive
Copy link
Contributor

Could you please try to force link the necessary classes like CGBitmapContext in your robovm.xml?
http://docs.robovm.com/user/1.0.0-SNAPSHOT/#__forcelinkclasses

@tomfisher
Copy link
Author

I did and failed as usual.

@ntherning ntherning added this to the 1.0.1 milestone Mar 19, 2015
@ntherning ntherning added the bug label Mar 19, 2015
@ntherning
Copy link
Contributor

I have test run your code in the simulator (32-bit iPad2 iOS 8.1) but it seems to be working just fine here. Is there something else I need to do to make it crash? You were talking about adding/removing methods? Is the code in https://github.com/tomfisher/issue837 the code that fails for you? Are you running on device or in the simulator? Which iOS version and (simulated) device?

@tomfisher
Copy link
Author

Sorry, the current code just demonstrates the brief scenario.

I am working on the local project and trying to remove unrelated code in order to submit a project that focuses on the problem. But the problem is any code removal magically eliminates the exception sometime and does not sometime without any observable pattern.

For the moment, we could guess it's a compile or linking problem. I would like share the project that still contains a a few code after days of removal if you don't mind.

@tomfisher
Copy link
Author

The full source code is uploaded to https://github.com/tomfisher/issue837. It fails on all simulators and devices, as well as on all iOS sdks. See code and comments in method thisIsTheExceptionSourceEvenNotUsed for how to eliminate the exception.

@tomfisher
Copy link
Author

Is there someone working on this? Don't know whether you guys can reproduce the bug with the above code.

@badlogic
Copy link
Contributor

Sorry, we are currently juggling a lot of balls, so things take a while. I just tried your sample project using RoboVM 1.0.0, compiling via Eclipse (i added <nature>org.robovm.eclipse.RoboVMNature</nature>) to the .project file). I don't get an error, instead i see this (32-bit simulator, release build):

http://sht.tl/WBx5cl

Next i tried running it via Maven (mvn test -P robosim). Again, no error:

http://sht.tl/MQ0sIi

This was with an empty cache. I recompiled and deployed to sim a couple more times via Maven, i never got an error.

I'm afraid as long as we can't reproduce it on our end, we can't do much :/

@tomfisher
Copy link
Author

Did you click the red area?

@tomfisher
Copy link
Author

I cleaned everything including mvn repo, robovm cache and eclipse cache and got the error in console.

I do hope you forgot clicking the red area :-)

@badlogic
Copy link
Contributor

Of course I did not click the red area :(

I'll check it tomorrow but can't make any promises on a fixe eta.
On Mar 25, 2015 12:33 AM, "tomfisher" notifications@github.com wrote:

I cleaned everything including mvn repo, robovm cache and eclipse cache
and got the error in console.

I do hope you forgot clicking the red area :-)


Reply to this email directly or view it on GitHub
#837 (comment).

@badlogic
Copy link
Contributor

Without doing anything, i now get this exception on startup:

java.lang.NullPointerException
    at playn.robovm.RoboCanvas.data(RoboCanvas.java:82)
    at playn.robovm.RoboCanvasImage.updateTexture(RoboCanvasImage.java:78)
    at playn.core.gl.ImageGL.createMainTex(ImageGL.java:79)
    at playn.core.gl.ImageGL.ensureTexture(ImageGL.java:43)
    at playn.robovm.RoboCanvasImage.ensureTexture(RoboCanvasImage.java:67)
    at playn.core.gl.AbstractImageGL.draw(AbstractImageGL.java:79)
    at playn.core.gl.AbstractImageGL.draw(AbstractImageGL.java:69)
    at playn.core.gl.ImageLayerGL.paint(ImageLayerGL.java:95)
    at playn.core.gl.GroupLayerGL.render(GroupLayerGL.java:184)
    at playn.core.gl.GroupLayerGL.paint(GroupLayerGL.java:177)
    at playn.core.gl.GL20Context.paint(GL20Context.java:70)
    at playn.robovm.RoboGraphics.paint(RoboGraphics.java:166)
    at playn.robovm.RoboPlatform.paint(RoboPlatform.java:277)
    at playn.robovm.RoboViewController$1.draw(RoboViewController.java:73)
    at org.robovm.apple.uikit.UIView.$cb$drawRect$(UIView.java)
    at org.robovm.apple.uikit.UIApplication.main(Native Method)
    at org.robovm.apple.uikit.UIApplication.main(UIApplication.java:362)
    at org.robovm.issue837.Main.main(Main.java:79)

Will continue investigating, but it may take a bit.

@tomfisher
Copy link
Author

So strange. ClassCastException happens constantly just when clicking the area in my environment, rather than NPE on startup.

@tomfisher
Copy link
Author

Hi, guys:

Are you still working on this issue? Is there anything that I can help ?

@ntherning
Copy link
Contributor

No one's working on it ATM but we'll keep it open. I know I tried your repo to try to reproduce it but I couldn't get it to crash here. @badlogic also tried but never got the same exception. So I think we're a bit out of ideas at the moment. You have tried all SDKs with the simulator and also on device, right? Which iOS version do you have on your device? What kind of device? Did you try with the latest Xcode 6.3?

@ntherning ntherning modified the milestones: 1.2, 1.1 Apr 14, 2015
@tomfisher
Copy link
Author

Ok, I'll give a try with the latest Xcode and let you know whether this exists.

@tomfisher
Copy link
Author

It worked just once with the latest Xcode and SDK. After recompiling another project involved with CGBitmapContext, then every project just failed as before.

Is is possible related with the compiling cache? I did remove ~/.robovm and workspace/.metadata/org.robovm.xx folders for the first compile and consequent compiles. Don't know why the first magically worked.

@badlogic
Copy link
Contributor

My guess is that PlayN and your project (and/or another project you depend
on) are pulling in different RoboVM versions. Can you check the dependency
tree of your PlayN project?
On Apr 14, 2015 6:36 PM, "tomfisher" notifications@github.com wrote:

It worked just once with the latest Xcode and SDK. After recompiling
another project involved with CGBitmapContext, then every project just
failed as before.

Is is possible related with the compiling cache? I did remove ~/.robovm
and workspace/.metadata/org.robovm.xx folders for the first compile and
consequent compiles. Don't know why the first magically worked.


Reply to this email directly or view it on GitHub
#837 (comment).

@tomfisher
Copy link
Author

I did clean everything and even try the RoboVM 1.1.0 using the case, and still got the error. Are you guys sure the error cannot be reproduced in your environment? The error will be shown just when clicking in the red square in the demo rather than during the compiling and linking process.

I am using:

uname -a

Darwin ThinkCenter 14.3.0 Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64 x86_64

xcodebuild -showsdks

OS X SDKs:
    OS X 10.9                       -sdk macosx10.9
    OS X 10.10                      -sdk macosx10.10

iOS SDKs:
    iOS 8.3                         -sdk iphoneos8.3

iOS Simulator SDKs:
    Simulator - iOS 8.3             -sdk iphonesimulator8.3

clang --version

Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix

mvn dependency:resolve

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Issue 837 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:resolve (default-cli) @ issue837 ---
[INFO] 
[INFO] The following files have been resolved:
[INFO]    com.threerings:tripleplay:jar:1.9:compile
[INFO]    com.googlecode.playn:playn-core:jar:1.9:compile
[INFO]    org.robovm:robovm-cocoatouch:jar:1.1.0:compile
[INFO]    org.robovm:robovm-objc:jar:1.1.0:compile
[INFO]    com.threerings:react:jar:1.4.1:compile
[INFO]    org.robovm:robovm-rt:jar:1.1.0:compile
[INFO]    com.samskivert:pythagoras:jar:1.4.2:compile
[INFO]    com.googlecode.playn:playn-robovm:jar:1.9:compile
[INFO]    org.java-websocket:Java-WebSocket:jar:1.3.0:compile
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

Is there any mismatching with what you use or anything else that I should check?

@samskivert
Copy link

FWIW: I also just checked out the project, and ran mvn clean test -Probosim (having not yet built anything with RoboVM 1.1.0 so I think my compiler cache was clean), and I'm seeing the CCE.

[ERROR] java.lang.ClassCastException: org.robovm.apple.coregraphics.CGContext cannot be cast to org.robovm.apple.coregraphics.CGBitmapContext
[ERROR] 
[ERROR]     at playn.robovm.RoboAbstractImage.draw(RoboAbstractImage.java)
[ERROR]     at playn.core.gl.AbstractCanvasGL.drawImage(AbstractCanvasGL.java)
[ERROR]     at playn.core.gl.AbstractCanvasGL.drawImage(AbstractCanvasGL.java)
[ERROR]     at org.robovm.issue837.Main$1$1.onPointerStart(Main.java)
[ERROR]     at playn.core.PointerImpl$1.interact(PointerImpl.java)
[ERROR]     at playn.core.PointerImpl$1.interact(PointerImpl.java)
[ERROR]     at playn.core.AbstractLayer.interact(AbstractLayer.java)
[ERROR]     at playn.core.AbstractLayer.interact(AbstractLayer.java)
[ERROR]     at playn.core.Dispatcher.tryInteract(Dispatcher.java)
[ERROR]     at playn.core.Dispatcher$1.dispatch(Dispatcher.java)
[ERROR]     at playn.core.Dispatcher.dispatch(Dispatcher.java)
[ERROR]     at playn.core.PointerImpl.onPointerStart(PointerImpl.java)
[ERROR]     at playn.robovm.RoboPointer.onTouchesBegan(RoboPointer.java)
[ERROR]     at playn.robovm.RoboViewController$1.touchesBegan(RoboViewController.java)
[ERROR]     at playn.robovm.RoboViewController$1.$cb$touchesBegan$withEvent$(RoboViewController.java)
[ERROR]     at org.robovm.apple.uikit.UIApplication.main(Native Method)
[ERROR]     at org.robovm.apple.uikit.UIApplication.main(UIApplication.java)
[ERROR]     at org.robovm.issue837.Main.main(Main.java)

My relevant infos:

% uname -a
Darwin usui 14.3.0 Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64 x86_64

% xcodebuild -showsdks
OS X SDKs:
    OS X 10.9                       -sdk macosx10.9

iOS SDKs:
    iOS 8.0                         -sdk iphoneos8.0

iOS Simulator SDKs:
    Simulator - iOS 7.1             -sdk iphonesimulator7.1
    Simulator - iOS 8.0             -sdk iphonesimulator8.0

% clang --version
Apple LLVM version 6.0 (clang-600.0.51) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix

% mvn dependency:resolve
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Issue 837 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:resolve (default-cli) @ issue837 ---
[INFO] 
[INFO] The following files have been resolved:
[INFO]    com.threerings:tripleplay:jar:1.9:compile
[INFO]    com.googlecode.playn:playn-core:jar:1.9:compile
[INFO]    org.robovm:robovm-cocoatouch:jar:1.1.0:compile
[INFO]    org.robovm:robovm-objc:jar:1.1.0:compile
[INFO]    com.threerings:react:jar:1.4.1:compile
[INFO]    org.robovm:robovm-rt:jar:1.1.0:compile
[INFO]    com.samskivert:pythagoras:jar:1.4.2:compile
[INFO]    com.googlecode.playn:playn-robovm:jar:1.9:compile
[INFO]    org.java-websocket:Java-WebSocket:jar:1.3.0:compile
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.877 s
[INFO] Finished at: 2015-04-20T17:48:45-07:00
[INFO] Final Memory: 12M/245M
[INFO] ------------------------------------------------------------------------

The last time I saw this was circa issue 728, but when I bumped to the release where that was CNR, the problem also went away for me. But as we're now discovering, that was probably a red herring. Something wiggled around and the bug wasn't being triggered, but it doesn't seem to have gone away.

I would also be happy to poke at things if there is more useful info we can provide.

@tomfisher
Copy link
Author

Guys,

Have you reproduced the error? I'll be really appreciated if you have any plan on this issue.

@ntherning
Copy link
Contributor

A stacktrace with linenumbers would help. I assume it's around this line in RoboAbstractImage: https://github.com/threerings/playn/blob/master/robovm/src/playn/robovm/RoboAbstractImage.java#L75.

I had a theory back in #728 about our CFType.Marshaler.toObject() method being incorrect:

static CFType toObject(Class<? extends CFType> cls, long handle, long flags, boolean retain) {
    if (handle == 0) {
        return null;
    }
    long typeId = getTypeID(handle);
    Class<? extends CFType> cfTypeClass = allCFTypeClasses.get(typeId);
    if (cfTypeClass != null) {
        cls = cfTypeClass;
    }
    CFType o = (CFType) NativeObject.Marshaler.toObject(cls, handle, flags);
    if (retain) {
        retain(handle);
    }
    return o;
}

I can see how this can fail when passing in CGBitmapContext as cls. CGBitmapContext is a type we made up, there's no equivalent in CoreGraphics. CoreGraphics uses CGContextRef all over the place. typeId in this piece of code should be the id returned by CGContextGetTypeID(). That would set cfTypeClass to our CGContext.class and an instance of that would be created rather than a CGBitmapContext instance.

What I don't understand is why this code works for some of us. It should fail always!

Wait, could be due to the code that populates allCFTypeClasses:

static {
    @SuppressWarnings("unchecked")
    Class<? extends CFType>[] classes = (Class<? extends CFType>[]) 
            VM.listClasses(CFType.class, ClassLoader.getSystemClassLoader());
    Class<?>[] emptyArgs = new Class<?>[0];
    final Class<?> cfTypeClass = CFType.class;
    for (Class<? extends CFType> cls : classes) {
        if (cls != cfTypeClass && (cls.getModifiers() & ABSTRACT) == 0) {
            try {
                java.lang.reflect.Method m = cls.getMethod("getClassTypeID", emptyArgs);
                Long typeId = (Long) m.invoke(null);
                allCFTypeClasses.put(typeId, cls);
            } catch (Throwable e) {
                // Ignore, because several of Apple's CFType subclasses don't contain a getClassTypeID() method.
            }
        }
    }
}

We should probably use Class.getDeclaredMethod() there. Class.getMethod() also looks in the superclass so for CGBitmapContext, which doesn't have a getClassTypeID() method the current code will return the getClassTypeID() from CGContext. Depending on the order of the classes in classes allCFTypeClasses will either have a mapping from the type id of CGContext to CGContext (correct) or to CGBitmapContext (incorrect). Could be that when you run the code you always get CGContext while we get CGBitmapContext. Let me change that to Class.getDeclaredMethod() and I'll see if I can reproduce the issue...

@ntherning
Copy link
Contributor

Ok, I can reproduce it when switching to using Class.getDeclaredMethod():

java.lang.ClassCastException: org.robovm.apple.coregraphics.CGContext cannot be cast to org.robovm.apple.coregraphics.CGBitmapContext
    at playn.robovm.RoboAbstractImage.draw(RoboAbstractImage.java:37)
    at playn.core.gl.AbstractCanvasGL.drawImage(AbstractCanvasGL.java:52)
    at playn.core.gl.AbstractCanvasGL.drawImage(AbstractCanvasGL.java:41)
    at org.robovm.issue837.Main$1$1.onPointerStart(Main.java:53)
    at playn.core.PointerImpl$1.interact(PointerImpl.java:141)
    at playn.core.PointerImpl$1.interact(PointerImpl.java:139)
    at playn.core.AbstractLayer.interact(AbstractLayer.java:392)
    at playn.core.AbstractLayer.interact(AbstractLayer.java:372)
    at playn.core.Dispatcher.tryInteract(Dispatcher.java:163)
    at playn.core.Dispatcher$1.dispatch(Dispatcher.java:60)
    at playn.core.Dispatcher.dispatch(Dispatcher.java:187)
    at playn.core.PointerImpl.onPointerStart(PointerImpl.java:82)
    at playn.robovm.RoboPointer.onTouchesBegan(RoboPointer.java:37)
    at playn.robovm.RoboViewController$1.touchesBegan(RoboViewController.java:54)
    at playn.robovm.RoboViewController$1.$cb$touchesBegan$withEvent$(RoboViewController.java)
    at org.robovm.apple.uikit.UIApplication.main(Native Method)
    at org.robovm.apple.uikit.UIApplication.main(UIApplication.java:368)
    at org.robovm.issue837.Main.main(Main.java:79)

I think I know how we can fix this...

@tomfisher
Copy link
Author

Great! wait your good news.

ntherning added a commit that referenced this issue Apr 24, 2015
…ould be

added to the allCFTypeClasses map in place of the superclass which actually
has the getClassTypeId() method. Changed CFType.Marshaler.toObject() to only
use the class from allCFTypeClasses if that class is a subclass of the class
passed to toObject(). (#837)
@ntherning
Copy link
Contributor

Ok, pushed a fix for this issue. Please test with the next nightly build tomorrow and let us know if the problem is gone. http://docs.robovm.com/advanced-topics/nightlies.html

@tomfisher
Copy link
Author

It works for the demo project, as well as the originated one.

Thanks you guys all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants