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

Can't get it to work #3

Closed
meydominic opened this issue Nov 12, 2015 · 17 comments
Closed

Can't get it to work #3

meydominic opened this issue Nov 12, 2015 · 17 comments

Comments

@meydominic
Copy link

Hey guys,
I need to work with some Objective-C classes from Java-8.
I'm working with MacOs10.11

If I try the sample (high level api) code, it works fine.
This is the code:

// Obtain reference to Singleton instance of Objective-C client
Client c = Client.getInstance();

// Create a new mutable array
Proxy array = c.sendProxy("NSMutableArray", "array");
array.send("addObject:", "Hello");
array.send("addObject:", "World");
array.send("addObject:", "Test String");

assertEquals(3, array.sendInt("count"));

String lastString = array.sendString("lastObject");
assertEquals("Test String", lastString);

But if I try it with other classes, it doesn't work and my application is crashin with this error:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007fff8ba47d32, pid=41313, tid=5891
#
# JRE version: Java(TM) SE Runtime Environment (8.0_66-b17) (build 1.8.0_66-b17)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.66-b17 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  [libsystem_c.dylib+0xd32]  strlen+0x12

I need to work with NSPrintInfo, NSPrintOperation and PDFDocument.
That's my code:

Client c = Client.getInstance();
        Proxy nsPrintInfo = c.sendProxy("NSPrintInfo", "printinfo");
        Proxy pdfDocument = c.sendProxy("PDFDocument", "pdfDocument");
        Proxy nsPrintOperation = c.sendProxy("NSPrintOperation", "nsPrintOperation", "pdfDocument");

        nsPrintInfo.send("setTopMargin:", "0.0");
        nsPrintInfo.send("setBottomMargin:", "0.0");
        nsPrintInfo.send("setLeftMargin:", "0.0");
        nsPrintInfo.send("setRightMargin:", "0.0");
        nsPrintInfo.send("setHorizontalPagination:", "NSFitPagination");
        nsPrintInfo.send("setVerticalPagination:", "NSFitPagination");
        nsPrintInfo.send("setPaperSize:", "NSMakeSize(595.275591, 841.88976378)");

        pdfDocument.send("initWithURL:", filename);

        nsPrintOperation.send("setShowsPrintPanel:", "NO");
        nsPrintOperation.send("setShowsProgressPanel:", "NO");

        boolean succeed = nsPrintOperation.sendBoolean("runOperation");

I get the crash with Proxy nsPrintInfo = c.sendProxy("NSPrintInfo", "printinfo");

I hope you can help me.

Thanks :)

@shannah
Copy link
Owner

shannah commented Nov 12, 2015

I see several problems with this.

When you all Client.sentProxy(String,String), there are a number of variants, but mostly, the first parameter is an Objective-C class name and the second argument is a message name, and subsequent arguments are parameters to the message.

E.g. the call

Proxy nsPrintInfo = c.sendProxy("NSPrintInfo", "printinfo");

Is the equivalent of calling id nsPrintInfo = [NSPrintInfo printinfo] in objective-C. Look at the docs for NSPrintInfo

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSPrintInfo_Class/

There is no message printinfo.

Perhaps you are looking for sharedPrintInfo. I.e. [NSPrintInfo sharedPrintInfo] ?

Through the objective-c bridge this would be

Proxy nsPrintInfo = c.sendProxy("NSPrintInfo", "sharedPrintInfo");

You make similar errors throughout this code.

What I sometimes do is write the code that I want (or close to it) in objective-c, then translate it into java using the objective-c bridge. That way it is easier to debug the process incrementally.

@shannah shannah closed this as completed Nov 12, 2015
@meydominic
Copy link
Author

Thanks for your comment 👍
That helps me a lot :)

I edited my code a bit and it's working but not completly ^^

Here the code:

        Client c = Client.getInstance();

        Proxy nsPrintInfo = c.sendProxy("NSPrintInfo", "sharedPrintInfo");

        nsPrintInfo.send("setTopMargin:", 0);
        nsPrintInfo.send("setBottomMargin:", 0);
        nsPrintInfo.send("setLeftMargin:", 0);
        nsPrintInfo.send("setRightMargin:", 0);
        nsPrintInfo.send("setHorizontalPagination:", "NSFitPagination");
        nsPrintInfo.send("setVerticalPagination:", "NSFitPagination");
        nsPrintInfo.send("setPaperSize:", "NSMakeSize(595.275591, 841.88976378)");

        Proxy nsUrl = c.sendProxy("NSURL", "fileURLWithPath:", filename);

        Proxy pdfDocument = c.sendProxy("PDFDocument", "initWithURL:", nsUrl);
        Proxy nsPrintOperation = c.sendProxy("NSPrintOperation", "nsPrintOperation", pdfDocument); // this line is still wrong

        nsPrintOperation.send("setShowsPrintPanel:", false);
        nsPrintOperation.send("setShowsProgressPanel:", false);

        boolean succeed = nsPrintOperation.sendBoolean("runOperation");

I know, that some nsPrintInfo calls are not right, but that's not the problem for now.

My question is, how can I pass a created Object/Proxy as argument to another call/function like
Proxy pdfDocument = c.sendProxy("PDFDocument", "initWithURL:", nsUrl);

The obj-c code for creating a pdfdocument is:
PDFDocument *pdfDocument = [[[PDFDocument alloc] initWithURL:fileURL] autorelease];
Ho do I get [PDFDocument alloc] initWithUrl to work?

Proxy pdfalloc = c.sendProxy("PDFDocument", "alloc"); does not work for me :/

PDFDocument is placed in sub-framework PDFKit in #import <Quartz/Quartz.h>
Do I have to do something special first?

And another question. I found a line of code on stackoverflow:
NSPrintOperation *op = [myPDFDoc getPrintOperationForPrintInfo:info autoRotate:YES];

How can I get this to work? Something like:
Proxy nsPrintOperation = c.sendProxy([Pointer to my pdfdocument], "getPrintOperationForPrintInfo:autoRotate:", [Pointer to my printinfo], true);

I hope you can help me again, thanks :)

@shannah
Copy link
Owner

shannah commented Nov 13, 2015

My question is, how can I pass a created Object/Proxy as argument to another call/function like
Proxy pdfDocument = c.sendProxy("PDFDocument", "initWithURL:", nsUrl);

Proxy pdfalloc = c.sendProxy("PDFDocument", "alloc");
pdfalloc.setProxy("initWithURL:", nsUrl);
pdfalloc.setProxy("autorelease");

The Client.chain() method may allow you to do this all in one shot, but I'm out of practice and don't remember the exact semantics off the top of my head.

NSPrintOperation *op = [myPDFDoc getPrintOperationForPrintInfo:info autoRotate:YES];

becomes

Proxy op = pdfalloc.sentProxy("getPrintOperationForPrintInfo:autoRotate:", info, true);

PDFDocument is placed in sub-framework PDFKit in #import <Quartz/Quartz.h>
Do I have to do something special first?

I think that is imported by default. But if you need to import a library, you can do that using the Native.loadLibrary method. See the example with webkit here:
https://github.com/shannah/Java-Objective-C-Bridge/blob/master/java/test/ca/weblite/objc/TestWebView.java#L20-L22

@shannah
Copy link
Owner

shannah commented Nov 13, 2015

One other tip. Constants like NSFitPagination can't be passed as the string constant name. You'll need to find their values and pass them that way. E.g.

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSPrintInfo_Class/#//apple_ref/c/tdef/NSPrintingPaginationMode

enum {
   NSAutoPagination = 0,
   NSFitPagination  = 1,
   NSClipPagination = 2
};

So Instead of

nsPrintInfo.send("setHorizontalPagination:", "NSFitPagination");

you would do

nsPrintInfo.send("setHorizontalPagination:", 1);

@meydominic
Copy link
Author

At first, thanks for answering :)
I looked into your webkit example and adapted it to my needs for PDFKit, but I didn't get it to work.
In my obj-c testproject I need to include "Quartz" Framework to get PDFDocument.
But even with or without Native.Loadlibrary for Quartz, I can't get PDFDocument to work.

Everytime on Proxy pdfalloc = c.sendProxy("PDFDocument", "alloc"); the application crashes with nearly same error message as in my first comment.

And I don't know how I can load a library/framework inside another one.
Native.loadLibrary("Quartz") works, but I don't get PDFDocument. But quartz.h includes PDFKit
Native.loadLibrary("PDFKit") doesn't work, because it can't find PDFKit.
PDFKit.Framework is inside Quartz.Framework/Frameworks/.

Any idea? Thanks :)

@shannah
Copy link
Owner

shannah commented Nov 15, 2015

Native.loadLibrary("Quartz") gets PDFDocument for me.

What happens when you do something like:

Native.loadLibrary("Quartz", PDFKit.class);
Proxy pdfalloc = c.sendProxy("PDFDocument", "alloc");

(Where PDFKit is just a dummy interface you created with no methods).

On Sun, Nov 15, 2015 at 3:41 AM, Dominic Eubel notifications@github.com
wrote:

At first, thanks for answering :)
I looked into your webkit example and adapted it to my needs for PDFKit,
but I didn't get it to work.
In my obj-c testproject I need to include "Quartz" Framework to get
PDFDocument.
But even with or without Native.Loadlibrary for Quartz, I can't get
PDFDocument to work.

Everytime on Proxy pdfalloc = c.sendProxy("PDFDocument", "alloc"); the
application crashes with nearly same error message as in my first comment.

And I don't know how I can load a library/framework inside another one.
Native.loadLibrary("Quartz") works, but I don't get PDFDocument. But
quartz.h includes PDFKit
Native.loadLibrary("PDFKit") doesn't work, because it can't find PDFKit.
PDFKit.Framework is inside Quartz.Framework/Frameworks/.

Any idea? Thanks :)


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

Steve Hannah
Web Lite Solutions Corp.

@meydominic
Copy link
Author

Native.loadLibrary("Quartz") gets PDFDocument for me.

This means:

Native.loadLibrary("Quartz");
Proxy pdfdocument = c.sendProxy("PDFDocument", "alloc");

should be enough to get PDFDocument? I need to test again at work on monday.

What happens when you do something like:

Native.loadLibrary("Quartz", PDFKit.class);
Proxy pdfalloc = c.sendProxy("PDFDocument", "alloc");

(Where PDFKit is just a dummy interface you created with no methods).

Do you mean like in WebKit example? :

    public static interface WebKit extends Library {
        public final static TestWebView.WebKit INSTANCE = (TestWebView.WebKit)Native.loadLibrary("WebKit", TestWebView.WebKit.class);
    }

Could look like adapted:

    public static interface Quartz extends Library {
        public final static TestClass.Quartz INSTANCE = (TestClass.Quartz)Native.loadLibrary("Quartz", TestClass.Quartz.class);
    }

and then
Native.loadLibrary("Quartz", TestClass.Quartz.class); ?

@shannah
Copy link
Owner

shannah commented Nov 15, 2015

On Sun, Nov 15, 2015 at 8:18 AM, Dominic Eubel notifications@github.com
wrote:

Native.loadLibrary("Quartz") gets PDFDocument for me.

This means:

Native.loadLibrary("Quartz");Proxy pdfdocument = c.sendProxy("PDFDocument", "alloc");

Yes. Except loadLibrary takes a second parameter. Pass it a dummy
interface. E.g. Native.loadLibrary("Quartz", MyInterface.class);

Steve

should be enough to get PDFDocument? I need to test again at work on
monday.


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

Steve Hannah
Web Lite Solutions Corp.

@meydominic
Copy link
Author

I updated my last comment :) Thanks 👍

Maybe you can post here a/your minimal code, with class, dummy interface and loadlibrary and pdfdocument alloc. So I only need to import it in my IDE and run it for testing.

@shannah
Copy link
Owner

shannah commented Nov 15, 2015

Here is a gist.
https://gist.github.com/shannah/2640dc55aadb988a51c0

I just used the WebView test and added some calls to instantiate a
PDFDocument. It doesn't actually do anything with it, but it compiles and
runs fine, which means that PDFDocument was loaded ok.

On Sun, Nov 15, 2015 at 8:25 AM, Dominic Eubel notifications@github.com
wrote:

I updated my last comment :) Thanks [image: 👍]


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

Steve Hannah
Web Lite Solutions Corp.

@meydominic
Copy link
Author

Thank you so much :) Will test it tomorrow 👍

@meydominic
Copy link
Author

So, I have tested it, but it doesn't really work.
It can create a PDFDocument object but it crashes directly after creating proxy:

Proxy pdfAlloc = c.sendProxy("PDFDocument", "alloc");

I get :

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007fff9291f93e, pid=46611, tid=5891
#
# JRE version: Java(TM) SE Runtime Environment (8.0_66-b17) (build 1.8.0_66-b17)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.66-b17 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  [PDFKit+0x893e]  -[PDFDocument pageCount]+0x16

@shannah
Copy link
Owner

shannah commented Nov 16, 2015

That crash doesn't look like it happens there. Do you do anything with the
pfdalloc object after creating it?
On Nov 15, 2015 10:46 PM, "Dominic Eubel" notifications@github.com wrote:

So, I have tested it, but it doesn't really work.
It can create a PDFDocument object but it crashes directly after creating
proxy:

Proxy pdfAlloc = c.sendProxy("PDFDocument", "alloc");

I get :

A fatal error has been detected by the Java Runtime Environment:

SIGSEGV (0xb) at pc=0x00007fff9291f93e, pid=46611, tid=5891

JRE version: Java(TM) SE Runtime Environment (8.0_66-b17) (build 1.8.0_66-b17)

Java VM: Java HotSpot(TM) 64-Bit Server VM (25.66-b17 mixed mode bsd-amd64 compressed oops)

Problematic frame:

C [PDFKit+0x893e] -[PDFDocument pageCount]+0x16


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

@meydominic
Copy link
Author

It's not possible for me to work with it because it crashes directly after/with
Proxy pdfAlloc = c.sendProxy("PDFDocument", "alloc");

@shannah
Copy link
Owner

shannah commented Nov 16, 2015

Please post test case. I can't reproduce. Works fine for me.
On Nov 16, 2015 6:22 AM, "Dominic Eubel" notifications@github.com wrote:

It's not possible for me to work with it because it crashes directly
after/with
Proxy pdfAlloc = c.sendProxy("PDFDocument", "alloc");


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

@meydominic
Copy link
Author

Mhhh, thats curious :/
I can post the test case tomorrow when I'm at work.
But I believe, that I only imported your gist in my IDE (IntelliJ) and ran it.
My Environment:
MacOsX 10.11 with JDK 1.8.0_66

@meydominic
Copy link
Author

I did a test again.

I used your gist and found out:

  • If I set a breakpoint in "myInit" method after pdfdocument alloc, application crashes with
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007fff9291f93e, pid=50122, tid=2571
#
# JRE version: Java(TM) SE Runtime Environment (8.0_66-b17) (build 1.8.0_66-b17)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.66-b17 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  [PDFKit+0x893e]  -[PDFDocument pageCount]+0x16

but if I put the breakpoint in another method (like someFuncWithMultipleArgs) then it runs fine and no crash.

Can you reproduce this case?

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

No branches or pull requests

2 participants