How to call Java method from perl6

use java::util::zip::CRC32:from<java>; my $crc = CRC32.new(); for 'Hello, Java'.encode('utf-8') { $crc.'method/update/(B)V'($_); } say $crc.getValue(); 

Unfortunately this does not work

 Method 'method/update/(B)V' not found for invocant of class 'java.util.zip.CRC32' 

This code is available at the following links. This is the only example I could find.

+6
source share
3 answers

Final answer

Combining the code cleanup described in the Orderly Response section below with the Pepe Schwartz enhancements mentioned in the Waiting warnings section below, we get:

 use java::util::zip::CRC32:from<Java>; my $crc = CRC32.new(); for 'Hello, Java'.encode('utf-8').list { $crc.update($_); } say $crc.getValue(); 

Your answer has been cleared.

 use v6; use java::util::zip::CRC32:from<Java>; my $crc = CRC32.new(); for 'Hello, Java'.encode('utf-8').list { # Appended `.list` $crc.'method/update/(I)V'($_); } say $crc.getValue(); 

One important bit changed is the added .list .

Fragment 'Hello, Java'.encode('utf-8') returns an object, a utf8 . This object returns only one value (itself) in the for statement. Thus, for iterates only once, passing the object to the code block using the update line.

Iteration only made sense once if the update line was .'method/update/([B)V' , which maps to a Java method that expects an 8-bit ints buffer, which is essentially what Perl 6 utf8 . However, this will require some Perl 6 support code (presumably in the main compiler) to marshal (automatically convert) Perl 6 utf8 to Java buf[] , and if that code ever existed / worked, it certainly doesn't work. when I test the last Rakudo.

But if you add a reasonable .list , as shown above, and change the code block to match, everything works.

First, .list causes the for statement to execute, iterating over a whole series of integers.

Secondly, like you, I named the Integer arg version of the Java method ( .'method/update/(I)V' ) instead of the original version of arg arg and the code worked correctly. (This means that the binary representation of the unsigned 8-bit integers returned from the Perl 6 utf8 object either already exactly matches the Java method or is automatically marshaled for you.)

Another required change is that from<java> should be from<java> for your comment below - thanks.

Waiting Warning

As of January 2015:

  • Simple use of the JVM server for Rakudo / NQP (i.e., running pure P6 code on the JVM) still requires more hardening before it can be officially declared ready for use. (This is in addition to the comprehensive hardening that is expected to take place throughout the year of the entire P6 ecosystem.) The JVM backend, I hope, will arrive there in 2015 - it will hopefully become part of the initial official launch of Perl 6, ready for production this year - but it will largely depend on demand and on the fact that there will be more developers using it and making corrections.

  • P6 code code invoking Java code is an optional project. Pepe Schwartz has made great strides in the last couple of months, reaching speed by studying the code base and

+6
source

The code that is responsible for this area of โ€‹โ€‹Java interaction is in the class org.perl6.nqp.runtime.BootJavaInterop . This assumes that overloaded methods are identified by the string method/<name>/<descriptor> . The org.objectweb.asm.Type#getMethodDescriptor evaluated in the org.objectweb.asm.Type#getMethodDescriptor . This jar is available through maven from http://mvnrepository.com/artifact/asm/asm .

 import java.util.zip.CRC32 import org.objectweb.asm.Type object MethodSignatures { def printSignature(cls: Class[_], method: String, params: Class[_]): Unit = { val m = cls.getMethod(method, params) val d = Type.getMethodDescriptor(m) println(m) println(s"\t$d") } def main(args: Array[String]) { val cls = classOf[CRC32] # see https://docs.oracle.com/javase/8/docs/api/java/util/zip/CRC32.html val ab = classOf[Array[Byte]] val i = classOf[Int] printSignature(cls, "update", ab) printSignature(cls, "update", i) } } 

Will print

 public void java.util.zip.CRC32.update(byte[]) ([B)V public void java.util.zip.CRC32.update(int) (I)V 

Since I want to call the update (int) variant of this overloaded method, the correct method call (on line 5 of the sample program)

 $crc.'method/update/(I)V'($_); 

This is crashing with

 This representation can not unbox to a native int 

finally, for some reason, I donโ€™t understand changing the same line to

 $crc.'method/update/(I)V'($_.Int); 

corrects this, and the example runs fine.

Final version of code

 use v6; use java::util::zip::CRC32:from<java>; my $crc = CRC32.new(); for 'Hello, Java'.encode('utf-8') { $crc.'method/update/(I)V'($_.Int); } say $crc.getValue(); 
+2
source

I got this to work on Perl 6.c with the following modification (January 4, 2018):

 use v6; use java::util::zip::CRC32:from<JavaRuntime>; my $crc = CRC32.new(); for 'Hello, Java'.encode('utf-8').list { $crc.update($_); } say $crc.getValue(); 

Result:

 % perl6-j --version This is Rakudo version 2017.12-79-g6f36b02 built on JVM implementing Perl 6.c. % perl6-j crcjava.p6 1072431491 
+1
source

Source: https://habr.com/ru/post/978748/


All Articles