Wink Saville’s Blog

February 23, 2008

Java - sources in jar’s

Filed under: java — wink @ 7:33 pm

While debugging Ajax support for AMC I learned that to debug class files that java libraries (aka. jar files) all you need to do is include the java files in the jar files.

February 12, 2008

Eclipse - ant and build.xml

Filed under: Android, Ant, Eclipse, java — wink @ 1:31 pm

This week I converted async-msgcomp to use ant for building rather than the internal Eclipse builders because it was the only way I could figure out to get jar files automatically built. After some trial an error I came up with common-build.xml which are common tasks for all sub-project and resides at the root of my build tree. I also created android-build.xml which is in the android sub-directory and is the common Ant tasks for Android. Then within each sub-project is a build.xml, for instance java/debug/build.xml and android/debug/build.xml as well as a global build.xml file in my root. For full disclosure; common-build.xml was based on the build.xml file emitted by:

File -> Export -> General -> Ant Buildfiles

And android-build.xml is based on the build.xml file emitted by running:

android-sdk/tools/activityCreator.py

The build.xml files are then used by executing ant in the appropriate sub directory. By executing ant in the root all of the sub-projects are built. Eclipse is also capable of building using Ant but you have setup the properties for each sub-project, which I’ll try to outline below. Sometimes Eclipse has trouble and either won’t execute saying they are still errors or it won’t execute because the classpath isn’t set properly.

One solution that has helped is to delete all projects and re-import them. Two other important items is that the Run parameters must be setup properly in <Run/Open Run Dialog> must be set properly and Build parameters for must be good.

Anyway, here is an example of setting the project properties so that external Ant files are used for compiling, in the example below I’m setup the sub-project “debug”. We assume there is a build.xml file in the sub-project.

Project -> Properties -> Builders -> new:

Main.Name: = debug-build.xml
Main.Buildfile: = Browse Worksapce => debug/build.xml
Main.Base Directory: = Browse Workspace => debug
Targets.After a “Clean”: = <default target selected>
Targets.Manual Build: = <default target selected>
Targets.Auto Build: = <default target selected>
Targets.During a “Clean”: = clean

Project -> Properties -> Builders = select only debug-build.xml deselect all others
Project -> Propertiers -> java Build Path -> Libraries = Add appropriate Libraries
Project -> Propertiers -> java Build Path -> Order and Export = the Libraries
Project -> Propertiers -> Project References -> Project references for debug: = select appropriate projects

In the Project -> Properties -> Builders where we select only debug-build.xml and deselect all others includes the following if it is an Android sub-project:

Android Resource Manager
Android Pre Compiler
Java Builder
Android Package Builder

If it is “pure java” project than you just deselect Java Builder.

January 5, 2008

Eclipse - line wrapping and indentation when formatting

Filed under: Eclipse, java — wink @ 11:45 am

Eclipse is a reasonable IDE and it has a reasonable pretty printer (Source/Format or Shift+Ctrl+F) except for one thing; when a function call exceeds 80 characters the formatting is terrible in my opinion:

/**
* Arguments
*/
class Example {
  void foo() {
    Other
             .bar(
                     100, 200, 300,
                     400, 500, 600,
                     700, 800, 900);
    }
}

Anyway, this can be changed by going to menu:

Window/Preferences/Java/Code Style/Formatter

Here you should make a “New” profile from an existing profile that is close to what you want, I used “Eclipse [built-in]” for my base, it was the default. And then select “Edit”. In the dialog box “Profile ‘….’” select “Line Wrapping” tab and then I changed “Maximum line width:” to 100 from 80 and then selected “Function Calls/Arguments” in the window below and then in the “Settings for agruments/Indentation policy:” selected “indent by one” this cured the formatting problem and now the above is:

/**
* Arguments
*/
class Example {
  void foo() {
    Other.bar(100, 200, 300, 400,
              500, 600, 700, 800, 900);
    }
}

Much better!

January 2, 2008

Java - class instance variable initialization

Filed under: java, programming — wink @ 5:37 pm

Been a few days, had a nice Christmas and New Years. Did work on Android and made good steady progress and nothing real interesting to report until today.

What was interesting is that I leaned that instance variables of class are initialized twice. The first time is before the constructor gets called the variables are initialized to the expected “zero” type defaults. boolean = false, byte/char/short/int = 0, float/double = 0.0 and object references to null.

Next the constructor is called and as the first instruction of the constructors executes values are at there defaults NOT any specific initialization, so don’t assume as I did. Usually this isn’t a problem but if you have inheritance thing can be surprising. In the example below when you instantiate X (new X()) we see:

X#overrideMe(): m=0
X#X(): m=4;

I would have naively expected both to print m=4!

    class B {
B() {
overrideMe();
}

void overrideMe() {
System.out.printf(”Not called\n”);
}
}

class X extends B {
X() {
System.out.printf(”X#X(): m=%d\n”, m);
}

@Override
void overrideMe() {
System.out.printf(”X#overrideMe(): m=%d\n”, m);
}

int m = 4;
}

What happens is that X#overrideMe is called while in the B#B() and m has only its default value zero and it doesn’t acquire its initialized value until after B#B() has completed.

December 23, 2007

Java - using javap

Filed under: java, programming — wink @ 12:30 pm

I wanted to disassemble a class using javap but unzipping android.jar navigating to android/os where Message.class resided and then executing:

javap -c Message.class

results in:

Couldnot find Message.class

I then searched for <javap Could not find> and found that specifying the class path and then the package name worked:

javap -c -classpath ~/android/android_sdk_linux_m3-rc37a/android.jar android.os.Message

Also, I could specify the unzipped jar, assume android.jar unzipped to android.xx and that works also:

javap -c -classpath ~/android/android_sdk_linux_m3-rc37a/android.xx android.os.Message

And the simplest was cd’ing into the directory with message and using “.” for classpath, that worked also:

cd android.xx/android/os/
javap -c -classpath . Message

Actually it turns out that if we go back to the original attempt but don’t leave off .class all is well , so assuming were still in android.xx/android/os then we just need:

javap -c Message

December 13, 2007

Java - How to find all classes implementing an interface

Filed under: Android, java, programming — wink @ 7:42 pm

For my state machine code I’d like to determine at runtime what states the user has created and what there hierarchy. I’ve created an interface that all states of a state machine must implement. My first thought was to use Annotation, but that didn’t work out, Android doesn’t seem to implement retrieving the annotation at runtime. So today I came up with the idea of using getClasses():

Class cl = this.getClass();
Class classes[] = cl.getClasses();

Log.v(df, “Hsm: Hsm() classes.length=” + classes.length);
for (Class c : classes) {
Log.v(df, “Hsm: class %s”, c.getName());
}

But that doesn’t work either:

I/ ( 587): Client: MyHsm() E name=TestHsmClient0
W/dalvikvm( 587): No implementation found for native java/lang/Class.getDeclaredClasses (Ljava/lang/Class;Z)[Ljava/lang/Class;
D/dalvikvm( 587): Exception java/lang/UnsatisfiedLinkError from Class.java:414 not caught locally
W/dalvikvm( 587): threadid=15: thread exiting with uncaught exception (group=0×4000e648)
E/AndroidRuntime( 587): Uncaught handler: thread TestHsmClient0 exiting due to uncaught exception
E/AndroidRuntime( 587): java.lang.UnsatisfiedLinkError: getDeclaredClasses
E/AndroidRuntime( 587): at java.lang.Class.getDeclaredClasses(Native Method)
E/AndroidRuntime( 587): at java.lang.Class.getFullListOfClasses(Class.java:414)
E/AndroidRuntime( 587): at java.lang.Class.getClasses(Class.java:172)
E/AndroidRuntime( 587): at com.saville.android.testhsm1.TestHsmClient$MyHsm.build(TestHsmClient.java:40)
E/AndroidRuntime( 587): at com.saville.android.testhsm1.TestHsmClient$MyHsm.<init>(TestHsmClient.java:34)
E/AndroidRuntime( 587): at com.saville.android.testhsm1.TestHsmClient.InitHsm(TestHsmClient.java:21)
E/AndroidRuntime( 587): at com.saville.android.hsm1.ActiveHsm.run(ActiveHsm.java:59)
E/AndroidRuntime( 587): at java.lang.Thread.run(Thread.java:896)
I/Process ( 461): Sending signal. PID: 587 SIG: 3
I/dalvikvm( 587): threadid=7: reacting to signal 3

Bummer.
I then searched for <java find all private classes> and came across this. “Locating all classes implementing a given interface?”. Exactly what I wanted, there were two replies to the post. One says use “ServiceLoader” the other says; “Manually scan the classes in the jar file” or “in your manifest.mf file”. Its interesting that Android has taken the approach of a manifest file. I did a quick search for ServiceLoader its manifest based also.

Java - Inheritance and constructors

Filed under: java, programming — wink @ 1:43 am

Here is a thread answering the question I had today concerning how a classes super class constructors are called. I had made a class which extended the Android Handler and everything worked. Later I came back and saw that I had a call to the super constructor commented out:

class StateMachine extends Handler {
StateMachine(String name) {
//super.Handler();
mName = name;
/* Other stuff */
}

Today I looked at this and wondered how it was working as I wasn’t calling the super class constructor. First the reason I had commented it out was because the syntax was wrong, it should have been “super();” not “super.Handler();”. But that didn’t answer the question, how/when should super class constructors be called in Java?

Turns out the answer is that the default constructor of the super class is always called if there is no explicit calls to super constructors, that is the reason my StateMachine class worked. In the above the last post we see:

Constructors are not inherited. The constructors that exist in a child class are completely independent of the ones that exist in the parent class.

If you do not define any expclicit constructors, the class will have the default, no-arg, do-nothing c’tor. If you define one or more c’tors, the class will not automatically have the default c’tor anymore.

Constructor rules:

1) Every class has at least one ctor.

1.1) If you do not define an explicit constructor for your class, the compiler provides a implicit constructor that takes no args and simply calls super().

1.2) If you do define one or more explicit constructors, regardless of whether they take args, then the compiler no longer provides the implicit no-arg ctor. In this case, you must explicitly define a

public MyClass() {}

if you want one.

1.3) Constructors are not inherited.

2) The first statement in the body of any ctor is either a call to a superclass ctor

super(…)

or a call to another ctor of this class

this(…)

2.1) If you do not explicitly put a call to super(…) or this(…) as the first statement in a ctor that you define, then the compiler implicitly inserts a call to super’s no-arg ctor

super()

as the first call. The implicitly called ctor is always super’s no-arg ctor, regardless of whether the currently running ctor takes args.

2.2) There is always exactly one call to either super(…) or this(…) in each constructor, and it is always the first call. You can’t put in more than one, and if you put one in, the compiler’s implicitly provided one is removed.

So I was lucky, sometimes that’s better than smart:)

Powered by WordPress