Kotlin JNI - Unsatisfied link error when calling external function but not when loading library - kotlin

C++ method signature:
JNIEXPORT void JNICALL
Java_abc_de_fg_jni_ProxyControls_startProxy(JNIEnv *env, jobject obj);
Loading the library doesn't cause any errors:
package abc.de.fg.jni
class ProxyControls {
init {
System.load("/Users/***/***/lib***.dylib")
println("loaded library")
}
external fun startProxy()
}
But running the startProxy method throws the error:
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: 'void abc.de.fg.jni.ProxyControls.startProxy()'
at abc.de.fg.jni.ProxyControls.startProxy(Native Method)
What have I done wrong?
More info:
Throwing an error on JNI_OnLoad crashes the app but throwing an error on startProxy() doesn't change the exception. So JNI_OnLoad is called but startProxy isn't called.
nm output: (filtered)
0000000000001e58 T _JNI_OnLoad
0000000000001ef4 T __Z51Java_abc_de_fg_jni_ProxyControls_startProxyP7JNIEnv_P8_jobject

Related

How to get full exception stacktrace when using await() on CompletableFuture

Problem
I am using kotlinx.coroutines.future.FutureKt#await to await for an async code. But when any exception is thrown from this async code, the Exception doesn't contain full stack call. E.g.:
fun main() {
try {
myFun1Blocking()
} catch (e: Throwable) {
e.printStackTrace(System.out)
}
}
fun myFun1Blocking() {
runBlocking {
myFun2Suspend()
}
}
suspend fun myFun2Suspend() {
runAsync().await()
}
fun runAsync(): CompletableFuture<Void> {
return CompletableFuture.runAsync {
Thread.sleep(2000)
throw Exception()
}
}
This results in the following output:
java.lang.Exception
at TestKotlinKt.runAsync$lambda-0(TestKotlin.kt:34)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1736)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1728)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
The stack trace only has the runAsync method part.
Solution #1
While trying to workaround this problem, I first thought of catching it just outside of await:
suspend fun <T> CompletionStage<T>.awaitWithException(): T {
try {
return await()
} catch (e: Exception) {
throw Exception(e)
}
}
java.lang.Exception: java.lang.Exception
at TestKotlinKt.awaitWithException(TestKotlin.kt:36)
at TestKotlinKt$awaitWithException$1.invokeSuspend(TestKotlin.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at TestKotlinKt.myFun1Blocking(TestKotlin.kt:23)
at TestKotlinKt.main(TestKotlin.kt:16)
at TestKotlinKt.main(TestKotlin.kt)
Caused by: java.lang.Exception
at TestKotlinKt.runAsync$lambda-0(TestKotlin.kt:43)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1736)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1728)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Better, but I still lost the myFun2Suspend call in the stack.
Solution #2
Then I tried saving the stacktrace just before await():
suspend fun <T> CompletionStage<T>.awaitWithException(printStream: PrintStream): T {
val throwable = Throwable("Await Exception")
try {
return await()
} catch (e: Exception) {
throwable.printStackTrace(printStream)
throw e
}
}
java.lang.Throwable: Await Exception
at TestKotlinKt.awaitWithException(TestKotlin.kt:43)
at TestKotlinKt.myFun2Suspend(TestKotlin.kt:31)
at TestKotlinKt$myFun1Blocking$1.invokeSuspend(TestKotlin.kt:26)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at TestKotlinKt.myFun1Blocking(TestKotlin.kt:25)
at TestKotlinKt.main(TestKotlin.kt:18)
at TestKotlinKt.main(TestKotlin.kt)
AsyncException
at TestKotlinKt.runAsync$lambda-0(TestKotlin.kt:55)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1736)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1728)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Now I see everything.
All in all, my solution seems to be very hacky. Is there something better?
Referring to Kotlin's documentation about debugging both of your solutions have officially supported counterparts:
Set the system property kotlinx.coroutines.debug to on to enable debug mode. This enables stacktrace recovery which is a more comprehensive version of solution #1.
Use the Kotlin debug agent to enable creation stacktraces which is the official version of solution #2. Do be aware that this is a very expensive feature because it will need to dump stack traces each time a coroutine is created.
In theory kotlin debug mode should be enough since the exception has to unwind through the 'stack' of coroutines. It just isn't the prettiest solution.
I faced the same problem. The Kotlin coroutine debug library didn't help me in any way.
Therefore, after studying the implementation of coroutines, I wrote my own solution based on bytecode generation and MethodHandle API. It supports JVM 1.8 and Android API 25 or higher.
I called it Stacktrace-decoroutinator.
The reason why the stacktrace is lost is that when the coroutine wakes up, only the last method of its call stack is called.
My library replaces the coroutine awakening implementation. It generates classes at runtime with names that match the entire coroutine call stack.
These classes don't do anything except call each other in the coroutine call stack sequence.
Thus, if the coroutine throws an exception, they mimic the real call stack of the coroutine during the creation of the exception stacktrace.

Velocity Initialization failing

I am using velocity as Java Code Generator, I am running a Eclipse application which has multiple plugins and different plugins are calling Velocity module for code generation.
Whenever i run a particular plugin it works fine individually no matter how many times i run it , Now if i will try to run the other plugin it throws velocity exception(i have provided stack trace below), I will restart the eclipse again and other plugin will work fine.
Conclusion: Velocity initialization fails when one plugin runs after some plugin already executed
The code i was using
velocityEngine = new VelocityEngine();
velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, LOCATION);
velocityEngine.setProperty(RESOURCE_LOADER,ClasspathResourceLoader.class.getName());
try {
velocityEngine.init();
} catch (Exception e) {
LOG.error("Failed to load velocity templates e={}", e);
}
i read it is caused by not able to create velocity.log file , then i tried it like this
velocityEngine = new VelocityEngine();
velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "class,file");
velocityEngine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.Log4JLogChute");
velocityEngine.setProperty("runtime.log.logsystem.log4j.logger", "VELLOGGER");
velocityEngine.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
velocityEngine.setProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.NullLogSystem");
/*
velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, LOCATION);
velocityEngine.setProperty(RESOURCE_LOADER,ClasspathResourceLoader.class.getName());
*/
try{
LOG.debug("Velocity Initialisation In AbstractFactory");
velocityEngine.init();
LOG.debug("Velocity Initialisation Done!!!");
}catch(Exception e){
LOG.error("Error Occured In Initialising Velocity Engine {}",e);
}
still it is failing while getting
template = velocityEngine.getTemplate(COMMAND_TEMPLATE_LOCATION.concat(command).concat(TEMPLATE_EXTENSION));
with exception stack trace:
org.apache.velocity.exception.VelocityException: Error initializing log: Failed to initialize an instance of org.apache.velocity.runtime.log.NullLogSystem with the current runtime configuration.
at org.apache.velocity.runtime.RuntimeInstance.initializeLog(RuntimeInstance.java:875)
at org.apache.velocity.runtime.RuntimeInstance.init(RuntimeInstance.java:262)
at org.apache.velocity.app.VelocityEngine.init(VelocityEngine.java:93)
at com.yodlee.dap.cortex.generation.engine.AbstractTemplateFactory.<init>(AbstractTemplateFactory.java:68)
at com.yodlee.dap.cortex.generation.engine.GenericTemplateFactory.<init>(GenericTemplateFactory.java:26)
at com.yodlee.dap.cortex.generation.generator.CodeGenerator.generateCode(CodeGenerator.java:52)
at com.yodlee.dap.cortex.codegenerator.processor.CodeGenProcessor.process(CodeGenProcessor.java:75)
at com.yodlee.dap.cortex.codegenerator.handler.CortexHandler.handle(CortexHandler.java:80)
at com.yodlee.dap.cortex.codegenerator.handler.CortexHandler.handle(CortexHandler.java:48)
at com.yodlee.dap.cortex.codegenerator.generate.CodeGenHandler.generate(CodeGenHandler.java:23)
at com.yodlee.eclipse.json.template.generator.code.TemplateGenerator.writeJavaFile(TemplateGenerator.java:228)
at com.yodlee.eclipse.json.template.generator.code.TemplateGenerator.findNewStates(TemplateGenerator.java:291)
at com.yodlee.eclipse.json.template.generator.code.TemplateGenerator.codeParser(TemplateGenerator.java:137)
at com.yodlee.eclipse.json.site.flow.CodeGenerator.generate(CodeGenerator.java:24)
at com.yodlee.eclipse.json.editor.JsonEditor.addBrowserContent(JsonEditor.java:310)
at com.yodlee.eclipse.json.editor.JsonEditor.setJsonInput(JsonEditor.java:450)
at com.yodlee.eclipse.json.editor.JsonReconcileStrategy$1.run(JsonReconcileStrategy.java:66)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:182)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4211)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3827)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610)
at org.eclipse.equinox.launcher.Main.run(Main.java:1519)
at org.eclipse.equinox.launcher.Main.main(Main.java:1492)
Caused by: org.apache.velocity.exception.VelocityException: Failed to initialize an instance of org.apache.velocity.runtime.log.NullLogSystem with the current runtime configuration.
at org.apache.velocity.runtime.log.LogManager.createLogChute(LogManager.java:220)
at org.apache.velocity.runtime.log.LogManager.updateLog(LogManager.java:269)
at org.apache.velocity.runtime.RuntimeInstance.initializeLog(RuntimeInstance.java:871)
... 42 common frames omitted
Caused by: org.apache.velocity.exception.VelocityException: The specified logger class org.apache.velocity.runtime.log.NullLogSystem does not implement the org.apache.velocity.runtime.log.LogChute interface.
at org.apache.velocity.runtime.log.LogManager.createLogChute(LogManager.java:181)
... 44 common frames omitted
12:32:52.177 [main] DEBUG com.yodlee.dap.cortex.generation.engine.GenericTemplateFactory - Start getGenericTemplate For= GenericClass
12:32:52.180 [main] ERROR com.yodlee.dap.cortex.generation.engine.GenericTemplateFactory - Error Occured In Velocity initialisation Module {}
org.apache.velocity.exception.VelocityException: Error initializing log: Failed to initialize an instance of org.apache.velocity.runtime.log.CommonsLogLogChute with the current runtime configuration.
at org.apache.velocity.runtime.RuntimeInstance.initializeLog(RuntimeInstance.java:875)
at org.apache.velocity.runtime.RuntimeInstance.init(RuntimeInstance.java:262)
at org.apache.velocity.app.VelocityEngine.init(VelocityEngine.java:93)
at com.yodlee.dap.cortex.generation.engine.GenericTemplateFactory.getGenericTemplate(GenericTemplateFactory.java:43)
at com.yodlee.dap.cortex.generation.generator.CodeGenerator.generateCode(CodeGenerator.java:52)
at com.yodlee.dap.cortex.codegenerator.processor.CodeGenProcessor.process(CodeGenProcessor.java:75)
at com.yodlee.dap.cortex.codegenerator.handler.CortexHandler.handle(CortexHandler.java:80)
at com.yodlee.dap.cortex.codegenerator.handler.CortexHandler.handle(CortexHandler.java:48)
at com.yodlee.dap.cortex.codegenerator.generate.CodeGenHandler.generate(CodeGenHandler.java:23)
at com.yodlee.eclipse.json.template.generator.code.TemplateGenerator.writeJavaFile(TemplateGenerator.java:228)
at com.yodlee.eclipse.json.template.generator.code.TemplateGenerator.findNewStates(TemplateGenerator.java:291)
at com.yodlee.eclipse.json.template.generator.code.TemplateGenerator.codeParser(TemplateGenerator.java:137)
at com.yodlee.eclipse.json.site.flow.CodeGenerator.generate(CodeGenerator.java:24)
at com.yodlee.eclipse.json.editor.JsonEditor.addBrowserContent(JsonEditor.java:310)
at com.yodlee.eclipse.json.editor.JsonEditor.setJsonInput(JsonEditor.java:450)
at com.yodlee.eclipse.json.editor.JsonReconcileStrategy$1.run(JsonReconcileStrategy.java:66)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:182)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4211)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3827)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:693)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:610)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:138)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610)
at org.eclipse.equinox.launcher.Main.run(Main.java:1519)
at org.eclipse.equinox.launcher.Main.main(Main.java:1492)
Caused by: org.apache.velocity.exception.VelocityException: Failed to initialize an instance of org.apache.velocity.runtime.log.CommonsLogLogChute with the current runtime configuration.
at org.apache.velocity.runtime.log.LogManager.createLogChute(LogManager.java:220)
at org.apache.velocity.runtime.log.LogManager.updateLog(LogManager.java:269)
at org.apache.velocity.runtime.RuntimeInstance.initializeLog(RuntimeInstance.java:871)
... 41 common frames omitted
Caused by: org.apache.velocity.exception.VelocityException: The specified logger class org.apache.velocity.runtime.log.CommonsLogLogChute does not implement the org.apache.velocity.runtime.log.LogChute interface.
at org.apache.velocity.runtime.log.LogManager.createLogChute(LogManager.java:181)
... 43 common frames omitted
Later i have found the actual root cause of the problem. It was whenever a plugin was initialising the velocity the other plugin was not able to re-initialise it, As the run time environment was same. Additionally both were present as separate module and hence it was not able to access it because of scope issue and hence velocity initialisation was failing.
The solution we implemented as we clubbed both the plugins under single module and hence initialised class from one module was accessible by other.
In my case veolocity and my application was initialized by 2 different class loaders. So when it tries to find the logger class in runtime it cannot find the class. As a solution I had to switched class loaders as a work around(anyway this is not a good way to solve this ).
VelocityEngine ve = new VelocityEngine();
Thread currentThread = Thread.currentThread();
ClassLoader temp = Thread.currentThread().getContextClassLoader();
try
{
currentThread.setContextClassLoader( getClass().getClassLoader() );
ve.setProperty( "runtime.log.logsystem.class", NullLogChute.class.getName() );
ve.init();
}
finally
{
currentThread.setContextClassLoader( temp );
}

NullPointerException when using advanced admob

After i change the admob lib from 'com.google.android.gms:play-services-ads:9.0.0' to 'com.google.firebase:firebase-ads:9.0.0', There is an exception happens
The crash log is :
java.lang.NullPointerException: Attempt to invoke interface method
'android.view.View xq.e()' on a null object reference
at rx.a(:com.google.android.gms.DynamiteModulesA:686)
at rr.a(:com.google.android.gms.DynamiteModulesA:3308)
at rr.onGlobalLayout(:com.google.android.gms.DynamiteModulesA:561)
at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:986)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2210)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1301)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7016)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
at android.view.Choreographer.doCallbacks(Choreographer.java:590)
at android.view.Choreographer.doFrame(Choreographer.java:560)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6946)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
And i report a bug in google group:
I am not sure what should i do to resolve this issue.
BR
Keven

Realm throws exception with empty unit test

In an Objective-C project, we started writing our new Unit Tests in Swift. I'm just now trying to create our first Unit Test of successfully saving the results of a parsed JSON. However, the test already fails during setup() due to the following error:
[ProjectTests.Project testInitializingOverlayCollectionCreatesAppropriateRealmObjects] : failed: caught "NSInvalidArgumentException", "+[RLMObjectBase ignoredProperties]: unrecognized selector sent to class 0x759b70
So apparently it tries to execute ignoredProperties on the RLMObjectBase class, and that method isn't implemented yet. Not sure how this happens, because I have yet to initialise anything, beyond creating a RLMRealms object with a random in-memory identifier.
ProjectTests.swift
import XCTest
class ProjectOverlayCollectionTests: XCTestCase {
var realm: RLMRealm!
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
let realmConfig = RLMRealmConfiguration()
realmConfig.inMemoryIdentifier = NSUUID().UUIDString
do {
realm = try RLMRealm(configuration: realmConfig) // <-- Crashes here.
}
catch _ as NSError {
XCTFail()
}
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testInitializingOverlayCollectionCreatesAppropriateRealmObjects() {
XCTAssertTrue(true)
}
}
Project-Bridging-Header.h
#import <Realm/Realm.h>
Podfile
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '7.1'
def shared_pods
pod 'Realm', '0.95.0'
end
target 'Project' do
shared_pods
end
target 'ProjectTests' do
shared_pods
end
As mentioned in the Realm documentation;
Avoid Linking Realm and Tested Code in Test Target
Remove the Realm pod from the ProjectTests target and all is right with the world.
Update: This answer is outdated. As #rommex mentions in a comment, following the current Realm installation documentation should link it to both your module and test targets without problems. However, I have not checked this.

Runtime exception when functional test running

public class MyTest extends FunctionalTest {
#Test
public void gtest() {
Http.Response response = GET("http://google.com"); // <--- RuntimeException
assertIsOk(response);
assertContentType("text/html", response);
assertCharset("utf-8", response);
}
}
This code throw :
java.lang.RuntimeException: java.util.concurrent.ExecutionException: play.exceptions.UnexpectedException: Unexpected Error
at play.test.FunctionalTest.makeRequest(FunctionalTest.java:299)
at play.test.FunctionalTest.makeRequest(FunctionalTest.java:305)
at play.test.FunctionalTest.GET(FunctionalTest.java:103)
at play.test.FunctionalTest.GET(FunctionalTest.java:57)
at MyTest.gtest(MyTest.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Can u tell why this error occurs ? And how to fix it? Playframework 1.2.4 / Java 1.7.0_02.
You probably just need to increase your execution pool size, which is by default 1 in dev mode (which also means test, by default). You're running out of threads and thus the exception occurs.
Try with a setting like this in your application.conf:
%test.play.pool=2