Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ACRA init crash using configuration with keystore factory #431

Closed
vdavy opened this issue Apr 14, 2016 · 6 comments
Closed

ACRA init crash using configuration with keystore factory #431

vdavy opened this issue Apr 14, 2016 · 6 comments

Comments

@vdavy
Copy link

vdavy commented Apr 14, 2016

Intro

I got a crash when initializing ACRA with a ACRAConfiguration when I call the setKeyStoreFactory method before.

Code causing crash

Here is the init code :

private void initACRA() {
        final KeyStore keyStore = getKeyStore();

        // The following line triggers the initialization of ACRA
        ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(this);
        configurationBuilder.setKeyStoreFactory(new KeyStoreFactory() {
            @Nullable
            @Override
            public KeyStore create(@NonNull Context context) {
                return keyStore;
            }
        });
        ACRAConfiguration acraConfiguration = configurationBuilder.build();
        ACRA.init(this, acraConfiguration);

        ACRA.getErrorReporter().setEnabled(getResources().getBoolean(R.bool.enable_acra));
    }

    @Nullable
    private KeyStore getKeyStore() {
        KeyStore keyStore = null;
        try {
            InputStream keystoreInputStream = getAssets().open(KEYSTORE_NAME);
            keyStore = KeyStore.getInstance("BKS");
            keyStore.load(keystoreInputStream, KEYSTORE_PASS.toCharArray());
            keystoreInputStream.close();
        } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException e) {
            Log.w(TAG, "Error opening keystore", e);
        }
        return keyStore;
    }

More info

The crashing line is ACRA.init(this, acraConfiguration);.
I'm using the version 4.8.5.

compile 'ch.acra:acra:4.8.5' (from my gradle file)

Code is available on github at this address : https://github.com/vdavy/android and speicifically this class https://github.com/vdavy/android/blob/master/station-millenium/src/main/java/com/stationmillenium/android/app/StationMilleniumApp.java

Stack trace

04-14 21:50:32.107 6133-6133/com.stationmillenium.android.debug E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.stationmillenium.android.debug, PID: 6133
java.lang.RuntimeException: Unable to create application com.android.tools.fd.runtime.BootstrapApplication: java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = org.acra.config.ACRAConfiguration)
 at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4710)
 at android.app.ActivityThread.-wrap1(ActivityThread.java)
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
 at android.os.Handler.dispatchMessage(Handler.java:102)
 at android.os.Looper.loop(Looper.java:148)
 at android.app.ActivityThread.main(ActivityThread.java:5417)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = org.acra.config.ACRAConfiguration)
 at android.os.Parcel.writeSerializable(Parcel.java:1447)
 at android.os.Parcel.writeValue(Parcel.java:1395)
 at android.os.Parcel.writeArrayMapInternal(Parcel.java:665)
 at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1330)
 at android.os.Bundle.writeToParcel(Bundle.java:1079)
 at android.os.Parcel.writeBundle(Parcel.java:690)
 at android.content.Intent.writeToParcel(Intent.java:7793)
 at android.app.ActivityManagerProxy.startService(ActivityManagerNative.java:3677)
 at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1240)
 at android.app.ContextImpl.startService(ContextImpl.java:1222)
 at android.content.ContextWrapper.startService(ContextWrapper.java:581)
 at org.acra.sender.SenderServiceStarter.startService(SenderServiceStarter.java:43)
 at org.acra.util.ApplicationStartupProcessor.sendApprovedReports(ApplicationStartupProcessor.java:75)
 at org.acra.ACRA.init(ACRA.java:230)
 at org.acra.ACRA.init(ACRA.java:156)
 at com.stationmillenium.android.app.StationMilleniumApp.initACRA(StationMilleniumApp.java:71)
 at com.stationmillenium.android.app.StationMilleniumApp.onCreate(StationMilleniumApp.java:52)
 at com.android.tools.fd.runtime.BootstrapApplication.onCreate(BootstrapApplication.java:326)
 at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1013)
 at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4707)
 at android.app.ActivityThread.-wrap1(ActivityThread.java) 
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405) 
 at android.os.Handler.dispatchMessage(Handler.java:102) 
 at android.os.Looper.loop(Looper.java:148) 
 at android.app.ActivityThread.main(ActivityThread.java:5417) 
 at java.lang.reflect.Method.invoke(Native Method) 
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by: java.io.NotSerializableException: com.stationmillenium.android.app.StationMilleniumApp
 at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1344)
 at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
 at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
 at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
 at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959)
 at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:360)
 at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1054)
 at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384)
 at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
 at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
 at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
 at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959)
 at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:360)
 at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1054)
 at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384)
 at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
 at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
 at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
 at android.os.Parcel.writeSerializable(Parcel.java:1442)
 at android.os.Parcel.writeValue(Parcel.java:1395) 
 at android.os.Parcel.writeArrayMapInternal(Parcel.java:665) 
 at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1330) 
 at android.os.Bundle.writeToParcel(Bundle.java:1079) 
 at android.os.Parcel.writeBundle(Parcel.java:690) 
 at android.content.Intent.writeToParcel(Intent.java:7793) 
 at android.app.ActivityManagerProxy.startService(ActivityManagerNative.java:3677) 
 at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1240) 
 at android.app.ContextImpl.startService(ContextImpl.java:1222) 
 at android.content.ContextWrapper.startService(ContextWrapper.java:581) 
 at org.acra.sender.SenderServiceStarter.startService(SenderServiceStarter.java:43) 
 at org.acra.util.ApplicationStartupProcessor.sendApprovedReports(ApplicationStartupProcessor.java:75) 
 at org.acra.ACRA.init(ACRA.java:230) 
 at org.acra.ACRA.init(ACRA.java:156) 
 at com.stationmillenium.android.app.StationMilleniumApp.initACRA(StationMilleniumApp.java:71) 
 at com.stationmillenium.android.app.StationMilleniumApp.onCreate(StationMilleniumApp.java:52) 
 at com.android.tools.fd.runtime.BootstrapApplication.onCreate(BootstrapApplication.java:326) 
 at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1013) 
 at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4707) 
 at android.app.ActivityThread.-wrap1(ActivityThread.java) 
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405) 
 at android.os.Handler.dispatchMessage(Handler.java:102) 
 at android.os.Looper.loop(Looper.java:148) 
 at android.app.ActivityThread.main(ActivityThread.java:5417) 
 at java.lang.reflect.Method.invoke(Native Method) 
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

I am something wrong or it is really a bug ?

@william-ferguson-au
Copy link
Member

I'm not seeing any immediate problem in the code you have posted.
Please post your ACRA config and your Application.onCreate() method.

@F43nd1r
Copy link
Member

F43nd1r commented Apr 14, 2016

Your KeyStoreFactory cannot be an anonymous inner class of a not serializable class, as these include a reference to the parent object, which is not serializable. Please export this class either to a completely seperate class or a static inner class. Also your KeyStoreFactory should create the keystore only when required, never before create is called (That is why a factory is passed at all).

@william-ferguson-au
Copy link
Member

:-) well spotted @F43nd1r

@vdavy
Copy link
Author

vdavy commented Apr 15, 2016

Thanks for your reply. It's working now.
Anyway, you should write in the method documentation you must not use an inner class and the keystore must not be create before the method is called. IMHO, this would be usefull.

Have a nice day.

@F43nd1r
Copy link
Member

F43nd1r commented Apr 15, 2016

@vdavy I have a different solution to this. See #432.

@william-ferguson-au
Copy link
Member

@vdavy It can be an inner class, it just needs to be static. The interface extends Serializable, your implementation should to. Extending Serializable is a big clue that the factory class needs to be static and contain no state. Very common in a factory pattern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants