Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: [XE10/Android/JSoup] Has anyone succeeded using JSoup in Delphi?


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 10 - Last Post: Jul 13, 2016 2:53 PM Last Post By: Remy Lebeau (Te...
Jörgen Hägglund

Posts: 4
Registered: 3/16/00
[XE10/Android/JSoup] Has anyone succeeded using JSoup in Delphi?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 12, 2016 5:45 PM
Hello!
I have been trying to get JSoup working in Delphi.
I simply ran Java2Op on it, added the .JAR to the libraries in my project and made sure the deployment path looked alright.
Then the problems began.
procedure TNetwork.InitialGet;
Var URL : JURL;
    Doc : Jnodes_DocumentClass;
begin
  URL := TJURL.JavaClass.init(StringToJString(<some URL>));
 
  Doc := TJJSoup.JavaClass.parse(URL, 15000) as JNodes_DocumentClass;
  // ** I tried this line below after modifying the JSoup unit to make connect return a JNodes_DocumentClass
  TJJSoup.JavaClass.connect(StringToJString(<some URL>)).get;
end;


I realize there are a couple of problems.
1) JSoup returns classes which only has static functions, but Java2Op thinks it returns instance classes.
2) I think I somehow should convert the JNodes_Document to the Delphi-like TJNodes_Document class, but I have no idea how to do that.

The result of my tests of the above code just terminates the app and the stack trace in the debugger makes me think it's something inside the JSoup class that fails due to a NULL-pointer, but I am not completely sure about this...

Anyone feeling the urge to help?

Best regards,
/Jörgen
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: [XE10/Android/JSoup] Has anyone succeeded using JSoup in Delphi?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 12, 2016 10:57 PM   in response to: Jörgen Hägglund in response to: Jörgen Hägglund
Jörgen wrote:

Doc : Jnodes_DocumentClass;

Doc := TJJSoup.JavaClass.parse(URL, 15000) as JNodes_DocumentClass;

JSoup.parse() returns a Document object, not a Document class type. Your
Doc variable needs to be declared as Jnodes_Document instead, and there should
be no cast needed on the parse() result at all.

I tried this line below after modifying the JSoup unit to make connect
return a JNodes_DocumentClass

Why did you make that change? Jsoup.connect() does not return a Document
class type, it returns a Connection object.

JSoup returns classes which only has static functions

No, it doesn't. The Document and Connection classes both have many non-static
methods in them.

but Java2Op thinks it returns instance classes.

Because JSoup really does return object instances, not class types. Clearly
you have read the JSoup documentation carefully enough. Do you think Java2Op
is lying to you?

I think I somehow should convert the JNodes_Document to the Delphi-like
TJNodes_Document class

No, you do not.

The result of my tests of the above code just terminates the app

Not surprising, since you are mangling the code and mismatching what JSoup
actually does.

Try this instead (I can't verify this myself, as my Java2Op is not able to
parse the latest JSoup jar file for some reason):

procedure TNetwork.InitialGet;
var
  URL : JURL;
  Doc : Jnodes_Document;
begin
  URL := TJURL.JavaClass.init(StringToJString(<some URL>));
  Doc := TJJSoup.JavaClass.parse(URL, 15000);
  // use Doc as needed...
end;


Or:

procedure TNetwork.InitialGet;
var
  Doc : Jnodes_Document;
begin
  Doc := TJJSoup.JavaClass.connect(StringToJString(<some URL>)).get();
  // use Doc as needed...
end;


--
Remy Lebeau (TeamB)
Jörgen Hägglund

Posts: 4
Registered: 3/16/00
Re: [XE10/Android/JSoup] Has anyone succeeded using JSoup in Delphi?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 13, 2016 7:31 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Jörgen wrote:

Doc : Jnodes_DocumentClass;

Doc := TJJSoup.JavaClass.parse(URL, 15000) as JNodes_DocumentClass;

JSoup.parse() returns a Document object, not a Document class type. Your
Doc variable needs to be declared as Jnodes_Document instead, and there should
be no cast needed on the parse() result at all.

I tried this line below after modifying the JSoup unit to make connect
return a JNodes_DocumentClass

Why did you make that change? Jsoup.connect() does not return a Document
class type, it returns a Connection object.

JSoup returns classes which only has static functions

No, it doesn't. The Document and Connection classes both have many non-static
methods in them.

but Java2Op thinks it returns instance classes.

Because JSoup really does return object instances, not class types. Clearly
you have read the JSoup documentation carefully enough. Do you think Java2Op
is lying to you?

I think I somehow should convert the JNodes_Document to the Delphi-like
TJNodes_Document class

No, you do not.

The result of my tests of the above code just terminates the app

Not surprising, since you are mangling the code and mismatching what JSoup
actually does.

Try this instead (I can't verify this myself, as my Java2Op is not able to
parse the latest JSoup jar file for some reason):

procedure TNetwork.InitialGet;
var
  URL : JURL;
  Doc : Jnodes_Document;
begin
  URL := TJURL.JavaClass.init(StringToJString(<some URL>));
  Doc := TJJSoup.JavaClass.parse(URL, 15000);
  // use Doc as needed...
end;


Or:

procedure TNetwork.InitialGet;
var
  Doc : Jnodes_Document;
begin
  Doc := TJJSoup.JavaClass.connect(StringToJString(<some URL>)).get();
  // use Doc as needed...
end;


--
Remy Lebeau (TeamB)

Thanks.
Your example follows the example from JSoup's site, but I still can't get it to work.
After reparsing the JSoup-1.9.2.jar, the JSoup_Connection is defined as:
  Jjsoup_ConnectionClass = interface(IJavaClass)
    ['{341C1D7E-7E1D-4C2E-88AC-601BA7C60FCF}']
    {class} function cookie(P1: JString; P2: JString): Jjsoup_Connection; cdecl;
    {class} function cookies(P1: JMap): Jjsoup_Connection; cdecl;
    {class} function data(P1: JMap): Jjsoup_Connection; cdecl; overload;
    {class} function data(P1: JCollection): Jjsoup_Connection; cdecl; overload;
    {class} function data(P1: JString): JConnection_KeyVal; cdecl; overload;
    {class} function data(P1: JString; P2: JString): Jjsoup_Connection; cdecl; overload;
    {class} function data(P1: JString; P2: JString; P3: JInputStream): Jjsoup_Connection; cdecl; overload;
    {class} function execute: JConnection_Response; cdecl;
    {class} function followRedirects(P1: Boolean): Jjsoup_Connection; cdecl;
    {class} function get: Jnodes_Document; cdecl;
    {class} function header(P1: JString; P2: JString): Jjsoup_Connection; cdecl;
    {class} function ignoreContentType(P1: Boolean): Jjsoup_Connection; cdecl;
    {class} function ignoreHttpErrors(P1: Boolean): Jjsoup_Connection; cdecl;
    {class} function maxBodySize(P1: Integer): Jjsoup_Connection; cdecl;
    {class} function method(P1: JConnection_Method): Jjsoup_Connection; cdecl;
    {class} function parser(P1: Jparser_Parser): Jjsoup_Connection; cdecl;
    {class} function post: Jnodes_Document; cdecl;
    {class} function postDataCharset(P1: JString): Jjsoup_Connection; cdecl;
    {class} function proxy(P1: JProxy): Jjsoup_Connection; cdecl; overload;
    {class} function proxy(P1: JString; P2: Integer): Jjsoup_Connection; cdecl; overload;
    {class} function referrer(P1: JString): Jjsoup_Connection; cdecl;
    {class} function request: JConnection_Request; cdecl; overload;
    {class} function request(P1: JConnection_Request): Jjsoup_Connection; cdecl; overload;
    {class} function requestBody(P1: JString): Jjsoup_Connection; cdecl;
    {class} function response: JConnection_Response; cdecl; overload;
    {class} function response(P1: JConnection_Response): Jjsoup_Connection; cdecl; overload;
    {class} function timeout(P1: Integer): Jjsoup_Connection; cdecl;
    {class} function url(P1: JURL): Jjsoup_Connection; cdecl; overload;
    {class} function url(P1: JString): Jjsoup_Connection; cdecl; overload;
    {class} function userAgent(P1: JString): Jjsoup_Connection; cdecl;
    {class} function validateTLSCertificates(P1: Boolean): Jjsoup_Connection; cdecl;
  end;
 
  [JavaSignature('org/jsoup/Connection')]
  Jjsoup_Connection = interface(IJavaInstance)
    ['{BFCFC97E-DAB6-4324-9142-922CDD9D1799}']
  end;
  TJjsoup_Connection = class(TJavaGenericImport<Jjsoup_ConnectionClass, Jjsoup_Connection>) end;

From what I understand there is only class functions, no instance functions. I.e. I can't call get() like in the example.
Actually, the Delphi compiler gives an error E2003: Undeclared identifier.

I am, as You've probably guessed, quite new to this JNI-integration stuff.
So, any help or pointers are greatly appreciated.

Regards,
/Jörgen
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: [XE10/Android/JSoup] Has anyone succeeded using JSoup in Delphi?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 13, 2016 10:22 AM   in response to: Jörgen Hägglund in response to: Jörgen Hägglund
Hello,

what you're missing (something I don't know on top of my head either) is
the mechanism to get an instance of this. After that you can call the
methods like regular Delphi object methods, just on that instance.

Greetings

Markus
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: [XE10/Android/JSoup] Has anyone succeeded using JSoup in Delphi?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 13, 2016 10:48 AM   in response to: Jörgen Hägglund in response to: Jörgen Hägglund
Jörgen wrote:

After reparsing the JSoup-1.9.2.jar, the JSoup_Connection is
defined as:

That translation does not match JSoup's documentation, or even the actual
Connection source code in the .jar file (I decompiled the .jar file to look
at its source).

All of the methods you listed are instance methods, not static methods, so
they should be in the Jjsoup_Connection interface instead of the Jjsoup_ConnectionClass
interface. The Connection class does not have any static methods. In fact,
I am not sure but I think Jjsoup_ConnectionClass should not even exist since
the .jar file does not actually define a Connection class at all, Connection
is an interface instead.

Document, on the other hand, is an actual class, and definately has both
static and non-static methods.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: [XE10/Android/JSoup] Has anyone succeeded using JSoup in Delphi?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 13, 2016 10:50 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy wrote:

That translation does not match JSoup's documentation, or even
the actual Connection source code in the .jar file (I decompiled
the .jar file to look at its source).

In other words, the output from Java2Op is very wrong, and that should be
reported as a bug to Quality Portal.

--
Remy Lebeau (TeamB)
Jörgen Hägglund

Posts: 4
Registered: 3/16/00
Re: [XE10/Android/JSoup] Has anyone succeeded using JSoup in Delphi?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 13, 2016 12:16 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Remy wrote:

That translation does not match JSoup's documentation, or even
the actual Connection source code in the .jar file (I decompiled
the .jar file to look at its source).

In other words, the output from Java2Op is very wrong, and that should be
reported as a bug to Quality Portal.

--
Remy Lebeau (TeamB)

Thanks!
Now reported as RSP-15473

Best regards,
/Jörgen
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: [XE10/Android/JSoup] Has anyone succeeded using JSoup in Delphi?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 13, 2016 1:13 PM   in response to: Jörgen Hägglund in response to: Jörgen Hägglund
Jörgen wrote:

Now reported as RSP-15473

I updated the ticket with more details and the actual .jar file. But since
my Java2Op is not working correctly, can you update the ticket to include
the actual Java2Op output?

--
Remy Lebeau (TeamB)
Jörgen Hägglund

Posts: 4
Registered: 3/16/00
Re: [XE10/Android/JSoup] Has anyone succeeded using JSoup in Delphi?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 13, 2016 1:49 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Jörgen wrote:

Now reported as RSP-15473

I updated the ticket with more details and the actual .jar file. But since
my Java2Op is not working correctly, can you update the ticket to include
the actual Java2Op output?

--
Remy Lebeau (TeamB)

Done.

/Jörgen
Eli M

Posts: 1,346
Registered: 11/9/13
Re: [XE10/Android/JSoup] Has anyone succeeded using JSoup in Delphi?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 13, 2016 2:25 PM   in response to: Jörgen Hägglund in response to: Jörgen Hägglund
I used Java2pas instead of Java2OP on the JSoup 1.9.2 jar. Maybe it converted it differently?

https://github.com/FMXExpress/jsoup-object-pascal-wrapper
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: [XE10/Android/JSoup] Has anyone succeeded using JSoup in Delphi?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 13, 2016 2:53 PM   in response to: Eli M in response to: Eli M
Eli wrote:

I used Java2pas instead of Java2OP on the JSoup 1.9.2 jar. Maybe it
converted it differently?

Yes, it is different.

Java2Pas did declare the non-static Connection methods in JConnection, where
they belong. But it also:

1. declared the same methods in JConnectionClass as well, like Java2Op does.
They don't belong there. I see the same issue in the code generated for
Connection's nested classes/interfaces as well.

2. generated incorrect [JavaSignature] attribute values for JConnection and
its nested classes/interfaces.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02