Skip to content

Commit

Permalink
Merge pull request #96 from qorelanguage/bugfix/3873_list_fix_094
Browse files Browse the repository at this point in the history
refs qorelanguage/qore#3873 use List<?> instead of ArrayList<?> as th…
  • Loading branch information
davidnich committed Apr 1, 2020
2 parents f2c9984 + e05b391 commit 55909c3
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 17 deletions.
3 changes: 3 additions & 0 deletions docs/mainpage.dox.tmpl
Expand Up @@ -476,6 +476,9 @@ set_save_object_callback(callback);
@section jnireleasenotes jni Module Release Notes

@subsection jni_1_1_2 jni Module Version 1.1.2
- use <tt>java.util.List&lt;?&gt;</tt> instead of <tt>java.util.ArrayList&lt;?&gt;</tt> as the base class for list
conversions
(<a href="https://github.com/qorelanguage/qore/issues/3873">issue 3873</a>)
- added the @ref org.qore.jni.Hash class to use when passing %Qore hashes to Java to make it easier to work with
%Qore hash data
(<a href="https://github.com/qorelanguage/qore/issues/3868">issue 3868</a>)
Expand Down
14 changes: 7 additions & 7 deletions src/Globals.cpp
Expand Up @@ -166,9 +166,9 @@ jmethodID Globals::methodHashPut;
GlobalReference<jclass> Globals::classMap;
jmethodID Globals::methodMapEntrySet;

GlobalReference<jclass> Globals::classAbstractList;
jmethodID Globals::methodAbstractListSize;
jmethodID Globals::methodAbstractListGet;
GlobalReference<jclass> Globals::classList;
jmethodID Globals::methodListSize;
jmethodID Globals::methodListGet;

GlobalReference<jclass> Globals::classSet;
jmethodID Globals::methodSetIterator;
Expand Down Expand Up @@ -1074,9 +1074,9 @@ void Globals::init() {
classMap = env.findClass("java/util/Map").makeGlobal();
methodMapEntrySet = env.getMethod(classMap, "entrySet", "()Ljava/util/Set;");

classAbstractList = env.findClass("java/util/AbstractList").makeGlobal();
methodAbstractListSize = env.getMethod(classAbstractList, "size", "()I");
methodAbstractListGet = env.getMethod(classAbstractList, "get", "(I)Ljava/lang/Object;");
classList = env.findClass("java/util/List").makeGlobal();
methodListSize = env.getMethod(classList, "size", "()I");
methodListGet = env.getMethod(classList, "get", "(I)Ljava/lang/Object;");

classSet = env.findClass("java/util/Set").makeGlobal();
methodSetIterator = env.getMethod(classSet, "iterator", "()Ljava/util/Iterator;");
Expand Down Expand Up @@ -1179,7 +1179,7 @@ void Globals::cleanup() {
classHash = nullptr;
//classLinkedHashMap = nullptr;
classMap = nullptr;
classAbstractList = nullptr;
classList = nullptr;
classSet = nullptr;
classEntry = nullptr;
classIterator = nullptr;
Expand Down
6 changes: 3 additions & 3 deletions src/Globals.h
Expand Up @@ -172,9 +172,9 @@ class Globals {
DLLLOCAL static GlobalReference<jclass> classMap; // java.util.Map
DLLLOCAL static jmethodID methodMapEntrySet; // Set<Map.Entry<K,V>> Map.entrySet()

DLLLOCAL static GlobalReference<jclass> classAbstractList; // java.util.AbstractList
DLLLOCAL static jmethodID methodAbstractListSize; // int AbstractList.size()
DLLLOCAL static jmethodID methodAbstractListGet; // Object AbstractList.get(int index)
DLLLOCAL static GlobalReference<jclass> classList; // java.util.List
DLLLOCAL static jmethodID methodListSize; // int List.size()
DLLLOCAL static jmethodID methodListGet; // Object List.get(int index)

DLLLOCAL static GlobalReference<jclass> classSet; // java.util.Set
DLLLOCAL static jmethodID methodSetIterator; // Set.iterator()
Expand Down
10 changes: 5 additions & 5 deletions src/JavaToQore.cpp
Expand Up @@ -2,7 +2,7 @@
//
// Qore Programming Language
//
// Copyright (C) 2016 - 2019 Qore Technologies, s.r.o.
// Copyright (C) 2016 - 2020 Qore Technologies, s.r.o.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -120,9 +120,9 @@ QoreValue JavaToQore::convertToQore(LocalReference<jobject> v) {
return rv.release();
}

if (env.isInstanceOf(v, Globals::classAbstractList)) {
// create list from AbstractList
jint size = env.callIntMethod(v, Globals::methodAbstractListSize, nullptr);
if (env.isInstanceOf(v, Globals::classList)) {
// create list from List
jint size = env.callIntMethod(v, Globals::methodListSize, nullptr);

ExceptionSink xsink;
ReferenceHolder<QoreListNode> rv(new QoreListNode(autoTypeInfo), &xsink);
Expand All @@ -133,7 +133,7 @@ QoreValue JavaToQore::convertToQore(LocalReference<jobject> v) {
jargs[0].i = pos++;

LocalReference<jobject> value = env.callObjectMethod(v,
Globals::methodAbstractListGet, &jargs[0]);
Globals::methodListGet, &jargs[0]);

ValueHolder val(convertToQore(value.release()), &xsink);
if (xsink) {
Expand Down
13 changes: 13 additions & 0 deletions test/java/src/org/qore/jni/test/QoreJavaApiTest.java
Expand Up @@ -255,6 +255,19 @@ public static String objectLifecycleTest(String arg) throws Throwable {
return (String)obj.callMethod("getString", arg);
}

public static void testHash1() throws Throwable {
Hash h = new Hash();
h.put("a", 1);
QoreJavaApi.callStaticMethod("TestHelper", "setHash", h);
}

public static void testHash2() throws Throwable {
Hash[] h = new Hash[1];
h[0] = new Hash();
h[0].put("a", 1);
QoreJavaApi.callStaticMethod("TestHelper", "setHashList", (Object)h);
}

public static boolean testHashBool(Hash h, String key) {
return h.getBool(key);
}
Expand Down
54 changes: 52 additions & 2 deletions test/jni.qtest
Expand Up @@ -34,6 +34,51 @@

%exec-class Main

class TestHelper {
private {
static hash<auto> hash_value = {};
}

static setHash(hash<auto> h) {
hash_value = h;
}

static setHashList(list<auto> l) {
hash_value = l[0];
}

static hash<auto> getHash() {
return hash_value;
}
}

class SimpleStringHandler inherits AbstractHttpRequestHandler {
private {
*string m_data;
string m_mime;
}
constructor(string mime, *string str) {
m_mime = mime;
m_data = str;
}
hash<auto> handleRequest(hash<auto> cx, hash<auto> hdr, *data body) {
if (hdr."do-error") {
return makeResponse(404, "test error", {"Content-Type": MimeTypeText});
}
if (hdr.method == "GET") {
return makeResponse(200, m_data ?? binary(body), {"Content-Type": m_mime});
} else if (hdr.method == "PUT") {
return makeResponse(200, m_data ?? binary(body), {"Content-Type": m_mime});
} else if (hdr.method == "PATCH") {
return makeResponse(200, m_data ?? binary(body), {"Content-Type": m_mime});
} else if (hdr.method == "POST") {
return makeResponse(200, m_data ?? binary(body), {"Content-Type": m_mime});
} else if (hdr.method == "DELETE") {
return makeResponse(404, m_data ?? binary(body), {"Content-Type": m_mime});
}
}
}

class DtorThrows {
destructor() {
throw "DTOR-ERROR";
Expand Down Expand Up @@ -142,8 +187,6 @@ public class Main inherits QUnit::Test {
addTestCase("callback return value test", \testCallbackRetVal());
addTestCase("special conversions test", \testSpecialConversions());
addTestCase("api test", \testQoreJavaApi());
/*
*/

# Return for compatibility with test harness that checks return value.
set_return_value(main());
Expand Down Expand Up @@ -772,6 +815,13 @@ lorem ipsum\r
assertEq("test", QoreJavaApiTest::testHashString({"a": "test"}, "a"));
assertEq((1, "two", True), QoreJavaApiTest::testHashList({"a": (1, "two", True)}, "a"));
assertEq({"a": 1, "b": "two"}, QoreJavaApiTest::testHashListIterator({"a": (1,), "b": ("two",)}));

QoreJavaApiTest::testHash1();
assertEq({"a": 1}, TestHelper::getHash());
TestHelper::setHash({});
assertEq({}, TestHelper::getHash());
QoreJavaApiTest::testHash2();
assertEq({"a": 1}, TestHelper::getHash());
}

testJniClasses() {
Expand Down

0 comments on commit 55909c3

Please sign in to comment.