Android Application class method onCreate being called multiple times - lifecycle

i've overloaded the Application class in my android app and i'm using the ACRA report system.
My app looks like ( real source code here ) :
public class MyApplication extends Application
{
#Override
public void onCreate() {
ACRA.init( this );
/*
* Initialize my singletons etc
* ...
* ...
*/
super.onCreate();
}
}
And as far as i know, the Application object should be created only once, so the onCreate method should be called only once.
The problem is, that in my crash reports ( from ACRA ) i have this:
java.lang.RuntimeException: Unable to create service it.evilsocket.myapp.net.N ...
java.lang.RuntimeException: Unable to create service it.evilsocket.myapp.net.NetworkMonitorService: java.lang.RuntimeException: Unable to create application it.evilsocket.myapp.MyApplication: **java.lang.IllegalStateException: ACRA#init called more than once**
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2283)
at android.app.ActivityThread.access$1600(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1212)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4441)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Unable to create application it.evilsocket.myapp.MyApplication: java.lang.IllegalStateException: ACRA#init called more than once
at android.app.LoadedApk.makeApplication(LoadedApk.java:495)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2269)
... 10 more
Caused by: java.lang.IllegalStateException: ACRA#init called more than once
at org.acra.ACRA.init(ACRA.java:118)
at it.evilsocket.myapp.MyApplication.onCreate(MyApplication.java:46)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:969)
at android.app.LoadedApk.makeApplication(LoadedApk.java:492)
... 11 more
java.lang.RuntimeException: Unable to create application it.evilsocket.myapp.MyApplication: java.lang.IllegalStateException: ACRA#init called more than once
at android.app.LoadedApk.makeApplication(LoadedApk.java:495)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2269)
at android.app.ActivityThread.access$1600(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1212)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4441)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: ACRA#init called more than once
at org.acra.ACRA.init(ACRA.java:118)
at it.evilsocket.myapp.MyApplication.onCreate(MyApplication.java:46)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:969)
at android.app.LoadedApk.makeApplication(LoadedApk.java:492)
... 11 more
java.lang.IllegalStateException: ACRA#init called more than once
at org.acra.ACRA.init(ACRA.java:118)
at it.evilsocket.myapp.MyApplication.onCreate(MyApplication.java:46)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:969)
at android.app.LoadedApk.makeApplication(LoadedApk.java:492)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2269)
at android.app.ActivityThread.access$1600(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1212)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4441)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
So it seems like the app onCreate is being called multiple times, any idea on this ?
NOTES:
In my android xml manifest, i did NOT use the
android:process="string" attribute.
Yes, i'm sure that in my initialization routines i'm not accidentally
calling MyApplication.onCreate .

I think that you have additional process in your application. That is why Application.onCreate is called more than once. Look into your manifest file and try to find the activity or service with something like android:process= . This means that activity/service is starting in second Dalvik VM, and that's why another application instance is created.

If you look at the stack trace, it looks like ACRA.init is calling makeApplication. I suspect that there's some sort of code to check if the application has been created already and if not, create it and that it is caused by your calling ACRA.init before super.onCreate. Generally when overriding onCreate methods (whether Application or Activity) it's recommended to call super.onCreate as the first line of your implementation and do your custom stuff afterwards. I'd give that a shot and see if it fixes things.

I'm also seeing this with ACRA 4.4.0 in the wild.
Perhaps something as simple as this under the init method?
if (mApplication != null) {
throw new IllegalStateException("ACRA#init called more than once");
//(return or finish or gracefully exit somehow)
} else {
mApplication = app;
//and then continue with rest of acra init...
Edit: 12/27/12 As a follow up to this, it looks like Kevin has adopted these changes. Details are here: https://github.com/ACRA/acra/commit/cda06f5b803a09e9e7cc7dafae2c65c8fa69b861

I have been looking at ACRA source code recently and think this issue has been addressed in ACRA in two ways:
Instead of onCreate(), now ACRA's doc recommends initializing ACRA
in attachBaseContext which is called before onCreate().
ACRA does have some logic to check if there are other ACRA instances
during the initialization. If yes, ACRA will unregister the existing
reporter and bypass the current reporter by some Proxy treatment.
Check init function in ACRA.kt

Related

Mocking a Supplier<>-Bean

I would like to mock a Bean (using mockito) that is defined like so
#Bean("idGenerator")
public Supplier<UUID> idGenerator() {
return () -> UUID.randomUUID();
}
In a SpringBootTest-class I get an error using #MockBean indicating, that that Bean cannot be mocked (due to some limitations in the JVM? - sorry, I don't have the stacktrace at hand right now).
I came up with a workaround that does not use Mocks but an additional field in a #TestConfiguration so that the return-value of the supplier can be specified externally.
Since I don't really like that workaround (and my colleagues won't either), I hope there is a proved pattern or the realization I am doing that mocking wrong.
Edit
Here is the stacktrace I am getting. As Markus pointed out - the standard unit-tests work - it seems to be a shortcoming of cucumber-java:
Before All/After All failed
io.cucumber.core.exception.CompositeCucumberException: There were 15 exceptions. The details are in the stacktrace below.
at io.cucumber.core.runtime.RethrowingThrowableCollector.getThrowable(RethrowingThrowableCollector.java:57)
at io.cucumber.core.runtime.CucumberExecutionContext.getThrowable(CucumberExecutionContext.java:102)
at io.cucumber.core.runtime.CucumberExecutionContext.finishTestRun(CucumberExecutionContext.java:97)
at io.cucumber.core.runtime.Runtime.execute(Runtime.java:96)
at io.cucumber.core.runtime.Runtime.run(Runtime.java:87)
at io.cucumber.core.cli.Main.run(Main.java:87)
at io.cucumber.core.cli.Main.main(Main.java:30)
Suppressed: java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124)
at io.cucumber.spring.TestContextAdaptor.<init>(TestContextAdaptor.java:32)
at io.cucumber.spring.SpringFactory.start(SpringFactory.java:120)
at io.cucumber.core.runner.Runner.buildBackendWorlds(Runner.java:134)
[...]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name [...]: Unsatisfied dependency expressed through constructor parameter 5: Initialization of bean failed;
nested exception is org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class BackendApplicationConfiguration$$Lambda$1713/0x00000008018fd980
Mockito cannot mock/spy because :
- VM does not support modification of given type
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229)
You can just define it like follows:
#MockBean(name = "idGenerator")
private Supplier<UUID> mockedSupplier;
there is no issue that prevents this from mocking. Would be good to include your stacktrace, as the issue is probably somewhere else.

AEM - after upgrade to JDK11 I can no longer pass class parameter to the scheduled job

After upgrade to JDK11 I'm no longer able to run some of my AEM 6.5 Sling jobs. It seems there is some problem with visibility of class that is used to pass parameters to the job.
Here is how the job is prepared and scheduled:
final Map<String, Object> props = new HashMap<String, Object>();
props.put("stringParam", "something");
props.put("classParam", new Dto());
Job job = jobManager.addJob("my/special/jobtopic", props);
The jobs is not started, as it seems there is any problem during job start, during parameters setup.
The stringParam is ok, but classParam usage throws following exception:
28.01.2022 17:28:25.978 *WARN* [sling-oak-observation-17] org.apache.sling.event.impl.jobs.queues.QueueJobCache
Unable to read job from /var/eventing/jobs/assigned/.../my.package.myJob/2022/1/27/15/50/...
java.lang.Exception: Unable to deserialize property 'classParam'
at org.apache.sling.event.impl.support.ResourceHelper.cloneValueMap(ResourceHelper.java:218)
at org.apache.sling.event.impl.jobs.Utility.readJob(Utility.java:181)
...
Caused by: java.lang.ClassNotFoundException: my.package.Dto
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at org.apache.sling.launchpad.base.shared.LauncherClassLoader.loadClass(LauncherClassLoader.java:160)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at org.apache.felix.framework.BundleWiringImpl.doImplicitBootDelegation(BundleWiringImpl.java:1817)
I'm pretty sure that the Dto class is visible and exported from my OSGI bundle, it can be used and consumed from another bundles. But for some reason internal sling logic is unable to resolve it. How can I make my Dto class accessible to internal Sling logic?
Any idea why does this happen and how to solve it?
The java.lang.ClassNotFoundException exception is misleading in this case.
The true reason for this problem is "Java Serialization Filter" that was added in JDK 9. It affects object deserialization rules.
I tried to do parameter serialization / deserialization myself and pass serialized object in base64 string:
String serializedString = job.getProperty("dto", String.class);
byte [] serializedBytes = Base64.getDecoder().decode(serializedString);
ByteArrayInputStream bais = new ByteArrayInputStream(serializedBytes);
ObjectInputStream ois = new ObjectInputStream(bais);
dtoParam = (Dto)ois.readObject();
Job was scheduled and run, however the result was java.io.InvalidClassException: filter status: REJECTED
It helped to find the true cause:
AEM implementation uses internal deserialization filter com.adobe.cq.deserfw.impl.FirewallSerialFilter that could be configured in OSGI Felix console. The component name is com.adobe.cq.deserfw.impl.DeserializationFirewallImpl.name.
Here add your class or package name.

project-reactor - Nullpointer when loading UUIDUtils with a failsafe integration test

I am running into a NP when running an integration test of the reactor EventBus with failsafe
I think this this because the class UUIDUtils is being loaded by the bootstrap classloader and hence the call to getClassLoader() is returning null?
Caused by: java.lang.NullPointerException
at reactor.core.support.UUIDUtils.<clinit>(UUIDUtils.java:39)
IS_THREADLOCALRANDOM_AVAILABLE = null != UUIDUtils.class.getClassLoader().loadClass(
"java.util.concurrent.ThreadLocalRandom"
);
Would you mind creating a GitHub issue on this so we can track a fix? Sounds like maybe we just need to try/catch setting this boolean and let it be false in this case.

Grails AOP config exception

I have a running grails app.
I upgraded the
springsecurity-core from 1.2.7.3 to 2.0-RC2
springsecurity-acl from 1.1.1 to 2.0-RC1
I added
springsecurity-oauth-provider 1.0.5.1
And I get an exception during startup:
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.codehaus.groovy.grails.commons.spring.TypeSpecifyableTransactionProxyFactoryBean]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at grails.plugin.springsecurity.acl.AclAutoProxyCreator.createProxy(AclAutoProxyCreator.java:120)
... 4 more
Caused by: java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
at net.sf.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
... 5 more
(only last part of ex)
The workaround was to remove the "#PreAuhthorize" annotations from the code. These versions of springSecurity don't work well together from some reason.

ClassNotFoundException on TableMapper when I use my own TableInputFormat

I am trying to use my own TableInputFormat for a MapReduceJob in the following way
TableMapReduceUtil.initTableMapperJob("mytable",
MyScan,
MyMapper.class,
MyKey.class,
MyValue.class,
myJob,true, MyTableInputFormat.class);
When I run the job, I get a ClassNotFoundException: org.apache.hadoop.hbase.mapreduce.TableMapper - any idea why ?
if I do not use the last two parameters of initTableMapperJob, then there is no ClassNotFoundException (but obviously that defeats the purpose)
I am struggling on this for few days now.
This is somewhere someone did the same thing Extending Hadoop's TableInputFormat to scan with a prefix used for distribution of timestamp keys, but I am not being able to ask the question on that thread.
I am working on a Cloudera Cluster 4.3.0 with Hadoop 2
Adding the stacktrace error:
java.lang.ClassNotFoundException: org.apache.hadoop.hbase.mapreduce.TableMapper at
java.net.URLClassLoader$1.run(URLClassLoader.java:202) at
java.security.AccessController.doPrivileged(Native Method) at
java.net.URLClassLoader.findClass(URLClassLoader.java:190) at
java.lang.ClassLoader.loadClass(ClassLoader.java:306) at
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at
java.lang.ClassLoader.loadClass(ClassLoader.java:247) at
java.lang.ClassLoader.defineClass1(Native Method) ....
Thanks a lot for helping
Regards
Please see Overriding TableMapper splits. So I overrode TableMapReduceUtil and added TableMapper.class to the addDependencyJars method. Then I proceeded in the same way
MyTableMapReduceUtil.initTableMapperJob("MyTable", // input table
myScan,
MyMapper.class,
MyKey.class,
MyValue.class,
myJob,
true,CustomSplitTableInputFormat.class);
Where CustomSplitTableInputFormat extends TableInputFormat

Resources