I've tried searching around both on Google and on stackoverflow for an answer to this, but I've been unable to find anyone with the exact issue I'm having. I'm attempting to set up a continuous integration server (Bamboo, specifically) to update, build, and export an APK every time someone makes a change in source control. I'm running into the same error both on my local machine when I do every step by hand and on the server when I use the job I've set up. The error happens when I reach the dex step of the build. I've gotten the same output so far with ant debug
, ant release
, ant clean debug
, and ant clean release
. The output of the entire dex step, complete with error, is as follows:
-dex: [dex] input: C:\Users\...\Android\bin\classes [dex] input: C:\Users\...\google-play-services_lib\bin\classes.jar [dex] input: C:\Program Files (x86)\Android\android-sdk\tools\support\annotations.jar [dex] input: C:\Users\...\Android\libs\FlurryAgent.jar [dex] input: C:\Users\...\Android\libs\gcm.jar [dex] input: C:\Users\...\Android\libs\android-support-v4.jar [dex] input: C:\Users\...\google-play-services_lib\libs\google-play-services.jar [dex] Pre-Dexing C:\Users\...\google-play-services_lib\bin\classes.jar -> classes-64c0adfe92ddc950c7ab8c5002ceabf2.jar [dex] Pre-Dexing C:\Program Files (x86)\Android\android-sdk\tools\support\annotations.jar -> annotations-62bab95d6948a2db17bbc7976160b014.jar [dex] Pre-Dexing C:\Users\...\Android\libs\FlurryAgent.jar -> FlurryAgent-499d43756a3ce626a64773e6dfd5eaec.jar [dex] Pre-Dexing C:\Users\...\Android\libs\gcm.jar -> gcm-ae2640f44640eb4fd7b13964b65d2d70.jar [dex] Pre-Dexing C:\Users\...\Android\libs\android-support-v4.jar -> android-support-v4-fa30b373a3e3ba9f2cf94900a9eb42fe.jar [dex] Pre-Dexing C:\Users\...\google-play-services_lib\libs\google-play-services.jar -> google-play-services-9efad6e9178399c185fae6c0b6bdc4c6.jar [dex] Converting compiled files and external libraries into C:\Users\...\Android\bin\classes.dex... [dx] [dx] UNEXPECTED TOP-LEVEL EXCEPTION: [dx] com.android.dx.util.ExceptionWithContext [dx] at com.android.dx.util.ExceptionWithContext.withContext(ExceptionWithContext.java:46) [dx] at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:344) [dx] at com.android.dx.dex.cf.CfTranslator.translate0(CfTranslator.java:134) [dx] at com.android.dx.dex.cf.CfTranslator.translate(CfTranslator.java:87) [dx] at com.android.dx.command.dexer.Main.processClass(Main.java:487) [dx] at com.android.dx.command.dexer.Main.processFileBytes(Main.java:459) [dx] at com.android.dx.command.dexer.Main.access$400(Main.java:67) [dx] at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:398) [dx] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:135) [dx] at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:191) [dx] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:123) [dx] at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:191) [dx] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:123) [dx] at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:191) [dx] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:123) [dx] at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:191) [dx] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:123) [dx] at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:191) [dx] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:123) [dx] at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:109) [dx] at com.android.dx.command.dexer.Main.processOne(Main.java:422) [dx] at com.android.dx.command.dexer.Main.processAllFiles(Main.java:333) [dx] at com.android.dx.command.dexer.Main.run(Main.java:209) [dx] at com.android.dx.command.dexer.Main.main(Main.java:174) [dx] at com.android.dx.command.Main.main(Main.java:91) [dx] Caused by: java.lang.NullPointerException [dx] at com.android.dx.cf.code.ConcreteMethod.<init>(ConcreteMethod.java:87) [dx] at com.android.dx.cf.code.ConcreteMethod.<init>(ConcreteMethod.java:75) [dx] at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:247) [dx] ... 23 more [dx] ...while processing <init> (Lcom/.../android/LocationService;)V [dx] ...while processing com/.../android/LocationService$1.class [dx] [dx] 1 error; aborting
For context, I'm using Ant v1.9.2 and Android build-tools v18.0.1 on a Windows machine and I haven't edited the build scripts in any way. I generated one for the app and one for the library using android update project --path .
in their two directories. I also haven't tried setting it up to automatically use the proper keystore for signing yet, although to my (limited) understanding that shouldn't be necessary, at least not for a debug build with Ant.
Has anyone seen this particular issue before? Is it a problem with the generated .class file? The build files? This is my first real foray into building with Ant (I generally just let Eclipse do all the hard work for me), so I have very little to go on. Any help would be much appreciated.
Update: In case anyone was paying attention to this question, my issue seems to have resolved itself. How and why, I don't know. I tried updating the source this morning (we had a few changes in), reran android update project -p .
, tried an ant clean debug
, and lo and behold, it worked. As did ant release
, which even signed it properly with the key I gave it. My best guess is that there was something weird in that LocationService class file, although what it was is beyond me.
Update 2: Anything I said in my first update is now invalid. I've isolated the issue, but am no closer to understanding it. This block of code is the culprit:
if (Settings.DEBUG) { Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread thread, Throwable ex) { storeDebugNotification(AndroidUncaughtExceptionHandler.getStackTraceString(ex)); } }); }
Here's where things get weird. When the Settings.DEBUG
flag is true
, this builds fine with ant. When it's false
, it fails, giving me the error shown above. When I comment the whole thing out, it works fine with either DEBUG
setting. The same goes for having the if (Settings.DEBUG)
line and its curly braces commented but the body left intact, as well as commenting the body and leaving the if portion alone. So... I'm at a loss here. Something about the interaction between the if statement and the body, in this particular file, when DEBUG
is false is causing problems. And the other weird part is that we have that exact same if block in another file in the app (an activity, whereas this one is a service).
By default, Android Studio builds the debug version of your app, which is intended for use only during development, when you click Run. To change the build variant Android Studio uses, select Build > Select Build Variant in the menu bar.
To start debugging an APK, click Profile or debug APK from the Android Studio Welcome screen. Or, if you already have a project open, click File > Profile or Debug APK from the menu bar. In the next dialog window, select the APK you want to import into Android Studio and click OK.
The tool windows give you access to specific tasks like project management, search, version control, and more. You can expand them and collapse them. The status bar displays the status of your project and the IDE itself, as well as any warnings or messages.
I had the same exception while compiling a project for release. My code was:
if (BuildConfig.DEBUG) { myView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Do something } }); }
Because BuildConfig.DEBUG is a constant with value false, the code in the block is recognized as dead code and removed when optimized.
The CfTranslator (Classfile Translator) wants to create a separate file for the anonymous class inside the block (SomeClass$1.class), but since it is optimized away an error will occur. I took the anonymous class outside the curly braces the problem was solved:
View.OnClickListener lClickListener = new View.OnClickListener() { @Override public void onClick(View v) { // Do something } }; if (BuildConfig.DEBUG) { myView.setOnClickListener(lClickListener); }
Update: Another way to solve this (described by @Ewoks in his answer below) is:
public boolean isInDeveloperMode() { return BuildConfig.DEBUG; } ... if (isInDeveloperMode()) { myView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Do something } }); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With