problem: accessing inner java class methods with bases java bindings
Sunday, 7 July 2019 · 2 messages · last reply 8 Jul 2019
FE
Florian Eckey7 Jul 2019 13:47 #
Hi,
I use basex java bindings in my project. It works fine but when I try to access inner java classes i cant find a way to get it work. I will use the SimpleJavaMail libs and there is a class called “MailerRegularBuilder” which is an inner class of “MailerBuilder”, especially with the method “buildMailer()”.
Here is a sample snippet of the based java class source code: public class MailerBuilder {
...
private MailerBuilder() { }
public static class MailerRegularBuilder extends MailerGenericBuilder<MailerRegularBuilder> { ...
public Mailer buildMailer() { return new Mailer(this);
}
...
}
}
In java I can easily access this method in the inner class with the following code (in red):
MailerRegularBuilder mailRegularBuilder = MailerBuilder.withSMTPServer("smtp.gmail.com", 465, "username1", "password1");
mailRegularBuilder = mailRegularBuilder.withProperty("mail.smtp.starttls.enable", "true");
mailRegularBuilder = mailRegularBuilder.withProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
Mailer inhouseMailer = mailRegularBuilder.buildMailer();
inhouseMailer.sendMail(email);
That works fine (remember it is only a snipped).
With XQuery I always get a class not found exception or a unknown method exception with the following code:
declare namespace Email = "java:org.simplejavamail.email.Email";
declare namespace EmailBuilder = "java:org.simplejavamail.email.EmailBuilder";
declare namespace Mailer = "java:org.simplejavamail.mailer.Mailer";
declare namespace MailerBuilder = "java:org.simplejavamail.mailer.MailerBuilder";
declare namespace EmailPopulatingBuilder = "java:org.simplejavamail.email.EmailPopulatingBuilder";
declare namespace MailerRegularBuilder = "java:org.simplejavamail.mailer.MailerBuilder.MailerRegularBuilder";
declare namespace MailerGenericBuilder = "java:org.simplejavamail.mailer.MailerGenericBuilder";
declare variable $local:fromName := "Florian Eckey";
declare variable $local:fromEmailAdress := "a.b at gmail.com";
declare variable $local:username := "username1"
declare variable $local:password := "password1";
declare variable $local:smtpServer := "smtp.gmail.com";
declare variable $local:smtpPort := 465;
declare function local:sendMail($toName, $toEmailAdress, $subject, $plainText, $attachementName, $attachement, $attachementType) {
let $emailPopulatingBuilder := EmailBuilder:starting-blank()
let $emailPopulatingBuilder := EmailPopulatingBuilder:from($emailPopulatingBuilder,$local:fromName, $local:fromEmailAdress)
let $emailPopulatingBuilder := EmailPopulatingBuilder:to($emailPopulatingBuilder,$toName, $toEmailAdress)
let $emailPopulatingBuilder := EmailPopulatingBuilder:withSubject($emailPopulatingBuilder,$subject)
let $emailPopulatingBuilder := if($attachement) then EmailPopulatingBuilder:withAttachment($attachementName, $attachement, $attachementType) else $emailPopulatingBuilder
let $emailPopulatingBuilder := EmailPopulatingBuilder:withPlainText($emailPopulatingBuilder,$plainText)
let $email := EmailPopulatingBuilder:buildEmail($emailPopulatingBuilder)
let $mailerRegularBuilder := MailerBuilder:withSMTPServer($local:smtpServer, xs:int($local:smtpPort), $local:username, $local:password)
let $mailerRegularBuilder := MailerGenericBuilder:withProperty($mailerRegularBuilder,"mail.smtp.starttls.enable", "true")
let $mailerRegularBuilder := MailerGenericBuilder:withProperty($mailerRegularBuilder,"mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory")
let $mailer := MailerRegularBuilder:buildMailer($mailerRegularBuilder) return (Mailer:sendMail($mailer,$email),"email send")
};
The red line will always throw the error: [XPST0017] Unknown class: org.simplejavamail.mailer.MailerBuilder.MailerRegularBuilder.
Beside: I copied all the used java libs into the lib folder of my basex instance. All other classes were found.
Does anyone have an idea how to access this inner class methods? Or is it not possible and I have to implement a custom java lib which masks the code in one static method?
Best regards,
Florian
PS: Sorry for the unhighlighted code, but it was just copied from the basex gui.
AB
Andy Bunce8 Jul 2019 16:22 #
Hi Florian,
It can be done, but it is perhaps a bit fragile.
You need to see now the class you want to reference is named after compilation(e.g in the jar). Often it will be of the form
outerclass$innerclass.class
A BaseX example accessing a inner class Builder from a Parser class [1]. Some general Java discussion [2]
/Andy
[1]
https://github.com/expkg-zone58/ex-markdown/blob/master/src/main/content/markdown.xqm#L12 [2]
https://stackoverflow.com/questions/2883181/why-is-an-anonymous-inner-class-containing-nothing-generated-from-this-code
Quoted text · Florian Eckey · 202 lines
On Sun, 7 Jul 2019 at 12:47, Florian Eckey <florian.eckey at googlemail.com> wrote: > Hi, > > > > I use basex java bindings in my project. It works fine but when I try to > access inner java classes i cant find a way to get it work. > > I will use the SimpleJavaMail libs and there is a class called > “MailerRegularBuilder” which is an inner class of “MailerBuilder”, > especially with the method “buildMailer()”. > > > > Here is a sample snippet of the based java class source code: > > public class MailerBuilder { > > > > ... > > > > private MailerBuilder() { > > } > > > > public static class MailerRegularBuilder extends MailerGenericBuilder<MailerRegularBuilder> { > > > > ... > > > > public Mailer buildMailer() { > > return new Mailer(this); > > } > > > > ... > > > > } > > } > > > > In java I can easily access this method in the inner class with the > following code (in red): > > > > MailerRegularBuilder mailRegularBuilder = MailerBuilder.*withSMTPServer*(" > smtp.gmail.com", 465, "username1", "password1"); > > mailRegularBuilder = mailRegularBuilder.withProperty( > "mail.smtp.starttls.enable", "true"); > > mailRegularBuilder = mailRegularBuilder.withProperty( > "mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); > > > > Mailer inhouseMailer = mailRegularBuilder.buildMailer(); > > > > inhouseMailer.sendMail(email); > > > > That works fine (remember it is only a snipped). > > With XQuery I always get a *class not found exception* or a *unknown > method exception* with the following code: > > > > declare namespace Email = "java:org.simplejavamail.email.Email"; > > declare namespace EmailBuilder = > "java:org.simplejavamail.email.EmailBuilder"; > > declare namespace Mailer = "java:org.simplejavamail.mailer.Mailer"; > > declare namespace MailerBuilder = > "java:org.simplejavamail.mailer.MailerBuilder"; > > declare namespace EmailPopulatingBuilder = > "java:org.simplejavamail.email.EmailPopulatingBuilder"; > > declare namespace MailerRegularBuilder = > "java:org.simplejavamail.mailer.MailerBuilder.MailerRegularBuilder"; > > declare namespace MailerGenericBuilder = > "java:org.simplejavamail.mailer.MailerGenericBuilder"; > > > > declare variable $local:fromName := "Florian Eckey"; > > declare variable $local:fromEmailAdress := "a.b at gmail.com"; > > declare variable $local:username := "username1" > > declare variable $local:password := "password1"; > > declare variable $local:smtpServer := "smtp.gmail.com"; > > declare variable $local:smtpPort := 465; > > > > declare function local:sendMail($toName, $toEmailAdress, $subject, > $plainText, $attachementName, $attachement, $attachementType) { > > let $emailPopulatingBuilder := EmailBuilder:starting-blank() > > let $emailPopulatingBuilder := > EmailPopulatingBuilder:from($emailPopulatingBuilder,$local:fromName, > $local:fromEmailAdress) > > let $emailPopulatingBuilder := > EmailPopulatingBuilder:to($emailPopulatingBuilder,$toName, $toEmailAdress) > > let $emailPopulatingBuilder := > EmailPopulatingBuilder:withSubject($emailPopulatingBuilder,$subject) > > let $emailPopulatingBuilder := if($attachement) then > EmailPopulatingBuilder:withAttachment($attachementName, $attachement, > $attachementType) else $emailPopulatingBuilder > > let $emailPopulatingBuilder := > EmailPopulatingBuilder:withPlainText($emailPopulatingBuilder,$plainText) > > > > let $email := EmailPopulatingBuilder:buildEmail($emailPopulatingBuilder) > > > > let $mailerRegularBuilder := > MailerBuilder:withSMTPServer($local:smtpServer, xs:int($local:smtpPort), > $local:username, $local:password) > > let $mailerRegularBuilder := > MailerGenericBuilder:withProperty($mailerRegularBuilder,"mail.smtp.starttls.enable", > "true") > > let $mailerRegularBuilder := > MailerGenericBuilder:withProperty($mailerRegularBuilder,"mail.smtp.socketFactory.class", > "javax.net.ssl.SSLSocketFactory") > > > > *let $mailer := MailerRegularBuilder:buildMailer($mailerRegularBuilder)* > > > > return (Mailer:sendMail($mailer,$email),"email send") > > }; > > > > The red line will always throw the error: *[XPST0017] Unknown class: > org.simplejavamail.mailer.MailerBuilder.MailerRegularBuilder.* > > > > Beside: I copied all the used java libs into the lib folder of my basex > instance. All other classes were found. > > > > Does anyone have an idea how to access this inner class methods? Or is it > not possible and I have to implement a custom java lib which masks the code > in one static method? > > > > Best regards, > > Florian > > > > PS: Sorry for the unhighlighted code, but it was just copied from the > basex gui. > > >
Written for BaseX 9.2. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery