Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify class in jar: android build failed

Tags:

java

android

jar

I want to change something in the jar file of the Barcode Scanner plugin for cordova, namely the RESULT_DISPLAY_DURATION_MS in the CaptureActivity class.

I unzipped it using the terminal (I'm on a mac).

Then, using ClassEditor, I looked up the class CaptureActivity, and changed the value. Next, I re-archived it using jar cfv samenameasoriginal.jar * . Then, I replaced the original jar-file for the new one.

The problem is, when I try to build it using ionic, I get a long list of errors, containing:

UNEXPECTED TOP-LEVEL EXCEPTION: com.android.dx.cf.iface.ParseException: bad attribute length; expected length 00000002 ... ...while parsing com/google/zxing/client/android/CaptureActivity.class

I've noticed that the new jar-file is 7 kb bigger than the original one, although I only changed the number 1500 to 9500, so that's a bit weird.

Anyone who can help me out? Looked online but found nothing...

like image 621
binoculars Avatar asked Aug 13 '15 19:08

binoculars


2 Answers

Extend from the class and adjust the value:

public class CustomCaptureActivity extends CaptureActivity {

    RESULT_DISPLAY_DURATION_MS = 9500; // wheras 9500 is your custom value
}

Instead of calling CaptureActivity now user your custom class.

If RESULT_DISPLAY_DURATION_MS is read-only: Copy & paste the methods using this variable to your custom class and replace the variable with a new constant defined in your own class. As long as CaptureActivity is not final this hopefully does the trick for you.

like image 116
sschmid Avatar answered Oct 16 '22 07:10

sschmid


I think that the problem is because when you are creating the JAR, there are some links that may relate to the old version of the file (because of optiomination reasons) and everything just crashes.

Not sure, but I think that's the reason.

So, instead of changing the file, you can use or a Decorator Design Patter (better idea, if possible) subclassing the class that you need to change with the changes ( https://en.wikipedia.org/wiki/Decorator_pattern ) or you can use reflection to modify directly the library.

Here there's an example of how to change a private final field. You can do something similar:

import java.lang.reflect.*;

public class EverythingIsTrue {
     static void setFinalStatic(Field field, Object newValue) throws Exception {
         field.setAccessible(true);

         Field modifiersField = Field.class.getDeclaredField("modifiers");
         modifiersField.setAccessible(true);
         modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

         field.set(null, newValue);
     }

     public static void main(String args[]) throws Exception {      
         setFinalStatic(Boolean.class.getField("FALSE"), true);

         System.out.format("Everything is %s", false); // "Everything is true"
     }
}
like image 22
Filnik Avatar answered Oct 16 '22 06:10

Filnik