NullPointerException from LeakCanary when running Robolectric tests - robolectric

Added LeakCanary (1.3) to my Application:
#Override
public void onCreate() {
super.onCreate();
Fabric.with(this, new Crashlytics());
LeakCanary.install(this);
When I run the Robolectric test suite for my application I get a NullPointerException in LeakCanary.
Caused by: java.lang.NullPointerException
at com.squareup.leakcanary.LeakCanary.isInServiceProcess(LeakCanary.java:165)
at com.squareup.leakcanary.LeakCanary.isInAnalyzerProcess(LeakCanary.java:141)
at com.squareup.leakcanary.LeakCanary.install(LeakCanary.java:52)
at com.squareup.leakcanary.LeakCanary.install(LeakCanary.java:43)
at com.package.application.MyApplication.onCreate(MyApplication.java:50)
at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:131)
at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:431)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:224)
I added that Im using Crashlytics to point out that it (and other methods as well) receives the same Application but does not throw any Exceptions.
Wasn't sure if this should be here or on GitHub issues for LeakCanary. Anyone else experiencing this issue?

Converting my comment to the answer.
Robolectric provides way to deal with different initialisations and application test lifecycles through test application.
Here is your application class:
public class <YourAppplication> extends Application {
#Override
public void onCreate() {
super.onCreate();
Fabric.with(this, new Crashlytics());
LeakCanary.install(this);
}
}
You should put in test sources in the same package as yours application next class:
public class Test<YourAppplication> extends <YourApplication> {
#Override
public void onCreate() {
}
}
Robolectric will load it instead of your application. As you can see I suppress all static initialisations from your application.
You can find more details here

A simple way to avoid the NullPointerException is to disable LeakCanary for unit tests by specifying the release (no-op) version in the testCompile directive in build.gradle. For instance:
dependencies {
...
testCompile (
'junit:junit:4.12',
'org.robolectric:robolectric:3.0',
'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
)
...
}

Related

"Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources" not found

I'm trying to create an integration test in .NET Core 2.1 with the latest Visual Studio 2017 build. There is nothing special about my setup whatsoever.
If I put the "async" keyword on a test, as is needed to test async methods, VS will terminate before attempting to run any tests with a FileNotFound exception. The missing file is "Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources".
So the question (other than 'how does Microsoft keep managing to release such broken frameworks') is: Why?
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ServiceClients.IntegrationTests
{
[TestClass]
public class SicklyUnitTest
{
[TestInitialize]
public void Initialize()
{
}
// This is fine
[TestMethod]
public void TrueIsTrue()
{
Assert.IsTrue(true);
}
// This causes FileNotFound - "Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.resources"
[TestMethod]
public async void DeOmnibusDubitandum()
{
Assert.IsTrue(true);
}
}
}

How to reduce slow start for picocli apps due to reflection

Picocli has to introspect the command tree. Doing so it needs to load the domain object classes for every Command which slows down the jvm startup.
What options are there to avoid this startup lag? One solution I've come up with is described in https://github.com/remkop/picocli/issues/482:
I am using reflection to postpone any class loading until after the command is selected. This way only the command classes themselves are loaded and finally the classes which implement the single command requested by the user:
abstract class BaseCommand implements Runnable {
interface CommandExecutor {
Object doExecute() throws Exception;
}
// find the CommandExecutor declared at the BaseCommand subclass.
protected Object executeReflectively() throws Exception {
Class<?> innerClass = getExecutorInnerClass();
Constructor<?> ctor = innerClass.getDeclaredConstructor(getClass());
CommandExecutor exec = (CommandExecutor) ctor.newInstance(this);
return exec.doExecute();
}
private Class<?> getExecutorInnerClass() throws ClassNotFoundException {
return getClass().getClassLoader().loadClass(getClass().getName() + "$Executor");
}
public void run() {
try {
executeReflectively();
} catch(...){
/// usual stuff
}
}
}
A concrete commend class:
#Command(...)
final class CopyProfile extends BaseCommand {
#Option String source;
#Option String dest;
// class must NOT be static and must be called "Executor"
public class Executor implements CommandExecutor {
#Override
public Object doExecute() throws Exception {
// you can basically wrap your original run() with this boilerplate
// all the CopyProfile's field are in scope!
FileUtils.copy(source, dest);
}
}
}
It seems like https://github.com/remkop/picocli/issues/500 may provide the ultimate solution to this. What are the other options until then?
UPDATE February 2020:
Upgrading to a recent version of picocli should fix this issue.
From the picocli 4.2.0 release notes:
From this release, subcommands are not instantiated until they are matched on the command line. This should improve the startup time for applications with subcommands that do a lot of initialization when they are instantiated.
An alternative that doesn’t require any code changes is to use GraalVM to compile your picocli-based application to a native image.
This article shows how to do this and the resulting startup time is 3 milliseconds.

error: cannot access zzb class file for com.google.firebase.iid.zzb not found

Getting error:
error: cannot access zzb
class file for com.google.firebase.iid.zzb not found
after including AccountKit:
compile 'com.facebook.android:account-kit-sdk:4.+'
Also onCreate & onDestroy is not getting resolved.
public class FirebaseInstanceIDService extends FirebaseInstanceIdService {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
Firebase & play services: v11.4.0
Firebase and play services libraries were older.
Upgraded them to v15.0.0 and accountkit to v4.32 resolved compile errors and build errors.
Update:
15.0.0 crashed at runtime when notification was received (fortunately app was in beta)
Stacktrace:
AbstractMethodError:firebase.iid.zzb.zzd(intent)
Solution-
Downgrading them to 11.8.0 worked.
(Accountkit v4.32)
Update: Also faced problem of not receiving push notification on Oreo 8.0
Solution- Notification not showing in Oreo

Xamarin.Forms: Forms.Context is obsolete

The new obsolete warning in Xamarin.Forms 2.5 really puzzled me.
What context should I be using in Dependency Services, for example, to call GetSystemService()?
Should I store in a static field the context of activity the xamarin forms were initialized against?
Should I override the android Application class and use its Context?
Should I call GetSystemService at activity create and save it somewhere?
I was having the same issue with several Dependency Services
The simplest solution
In a lot of cases for Single Activity Applications
Xamarin.Forms.Forms.Context
Can be replaced with
Android.App.Application.Context
The Background in more detail
Android.App.Application.Context returns the global Application Context of the current process tied to the lifecycle of the Application, as apposed to an Activity context.
A typical example of using the Application context is for starting an Activity e.g.
Android.App.Application.Context.StartActivity(myIntent);
The general rule of thumb is to use the current Activity Context, unless you need
to save a reference to a context from an object that lives beyond your
Activity. In which case use the Application context
Why did Forms.Context go obsolete?
Xmarin.Forms 2.5 introduced a new "Forms embedding" feature, which can embed Forms pages into Xamarin.iOS / Xamarin.Android apps. However, since Xamarin.Android apps can use multiple Activities, seemingly there was a danger of Xamarin.Android users calling Forms.Context and in turn getting a reference to the MainActivity, which has the potential cause problems.
The work around
Inside a Renderer you now get a reference to the view’s context which is passed into the constructor.
With any other class you are faced with the issue of how to get the Activity Context. In a single Activity application (in most cases) the Application.Context will work just fine.
However to get the current Activity Context in a Multiple Activity Application you will need to hold a reference to it. The easiest and most reliable way to do this is via a class that implements the Application.IActivityLifecycleCallbacks Interface.
The main idea is to keep a reference of the Context when an Activity
is created, started, or resumed.
[Application]
public partial class MainApplication : Application, Application.IActivityLifecycleCallbacks
{
internal static Context ActivityContext { get; private set; }
public MainApplication(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer) { }
public override void OnCreate()
{
base.OnCreate();
RegisterActivityLifecycleCallbacks(this);
}
public override void OnTerminate()
{
base.OnTerminate();
UnregisterActivityLifecycleCallbacks(this);
}
public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
{
ActivityContext = activity;
}
public void OnActivityResumed(Activity activity)
{
ActivityContext = activity;
}
public void OnActivityStarted(Activity activity)
{
ActivityContext = activity;
}
public void OnActivityDestroyed(Activity activity) { }
public void OnActivityPaused(Activity activity) { }
public void OnActivitySaveInstanceState(Activity activity, Bundle outState) { }
public void OnActivityStopped(Activity activity) { }
}
With the above approach, single Activity Applications and multiple Activity Applications can now always have access to the Current/Local Activity Context. e.g instead of relying on the global context
Android.App.Application.Context
// or previously
Xamarin.Forms.Forms.Context
Can now be replaced with
MainApplication.ActivityContext
Example call in a Dependency Service
if (MainApplication.ActivityContext!= null)
{
versionNumber = MainApplication.ActivityContext
.PackageManager
.GetPackageInfo(MainApplication.ActivityContext.PackageName, 0)
.VersionName;
}
Additional Resources
Android.App.Application.IActivityLifecycleCallbacks
registerActivityLifecycleCallbacks
In the latest scaffold of a new Xamarin Forms solution the CrossActivityPlugin (https://github.com/jamesmontemagno/CurrentActivityPlugin) is referenced in the Android project. So you can use
CrossCurrentActivity.Current.Activity.StartActivity(myIntent)

javafx programmatically set arguments for virtual keyboard

I have a desktop application that will be used on computers with no keyboard, input will be on a touch screen. I can get the virtual keyboard to show up on textfields fine when running from eclipse. I used these arguments
-Dcom.sun.javafx.touch=true
-Dcom.sun.javafx.isEmbedded=true
-Dcom.sun.javafx.virtualKeyboard=none
The following link shows me where to add the arguments.
how to add command line parameters when running java code in Eclipse?
When I make a runnable jar file the keyboard does not show up. I am looking for a way to set these arguments programmatically so that the runnable jar file will display the virtual keyboard on any computer. Any help will be greatly appreciated.
The only working solution I could find came from here
Gradle build for javafx application: Virtual Keyboard is not working due to missing System property
Create a wrapper class and set the system properties before invoking the applications original main method.
public class MainWrapper {
public static void main(String[] args) throws Exception
{ // application - package name
Class<?> app = Class.forName("application.Main");
Method main = app.getDeclaredMethod("main", String[].class);
System.setProperty("com.sun.javafx.isEmbedded", "true");
System.setProperty("com.sun.javafx.touch", "true");
System.setProperty("com.sun.javafx.virtualKeyboard", "javafx");
Object[] arguments = new Object[]{args};
main.invoke(null, arguments);
}
}
When making the runnable jar file just point to the MainWrapper class for the launch configuration.
The -D option to the JVM sets a system property. So you can achieve the same by doing the following:
public class MyApplication extends Application {
#Override
public void init() {
System.setProperty("com.sun.javafx.touch", "true");
System.setProperty("com.sun.javafx.isEmbedded", "true");
System.setProperty("com.sun.javafx.virtualKeyboard", "none");
}
#Override
public void start(Stage primaryStage) {
// ...
}
}

Resources