Can't build Android native extension - undefined base

I've written a native extension and implemented for iOS. Now want to implement for Android.

Right now, just trying to implement and test calcSumm(), but having no luck building.

All I have changed from the generated code is to remove getPlatformString() and joinStrings() demo functions (keeping calcSumm()).

I get:

Compiling java sources: ["/Users/jon/workspace/Sargent/build/android/singer/development/bin/tmp/RhodesSRC_build.files"]

PWD: /Users/jon/.rvm/gems/ruby-2.2.2@rhodes-5.0.30-sp3-57e9d466-watusi/gems/rhodes-5.0.30

CMD: /Library/Java/Home/bin/javac -g -d /Users/jon/workspace/Sargent/build/android/singer/development/bin/tmp/Rhodes -source 1.6 -target 1.6 -nowarn -encoding latin1 -classpath /Users/jon/sdk/android/sdk/platforms/android-22/android.jar:/Users/jon/workspace/Sargent/build/android/singer/development/bin/tmp/Rhodes:/Users/jon/sdk/android/sdk/extras/android/support/v4/android-support-v4.jar @/Users/jon/workspace/Sargent/build/android/singer/development/bin/tmp/RhodesSRC_build.files

Note: Some input files use or override a deprecated API.

Note: Recompile with -Xlint:deprecation for details.

Note: Some input files use unchecked or unsafe operations.

Note: Recompile with -Xlint:unchecked for details.

PWD: /Users/jon/workspace/Sargent/build/android/singer/development/bin/tmp/Rhodes

CMD: /Library/Java/Home/bin/jar cf /Users/jon/workspace/Sargent/build/android/singer/development/bin/target/android/release/librhodes/Rhodes.jar .

-$TIME$- message [ build:android:rhodes FINISH ] time is { 2015-04-26T20:56:42Z } milliseconds from start (7139)

-$TIME$- message [ build:android:extensions_java START ] time is { 2015-04-26T20:56:42Z } milliseconds from start (7140)

Compile extensions java code

/Users/jon/workspace/Sargent/build/android/singer/development/bin/target/android/release/extensions/coreapi/coreapi.jar is uptodate: true

Compiling java sources: ["/var/folders/qs/mry441454mq56w00y5f59c200000gn/T/BonjourBrowserSRC_build20150426-39991-foco3u"]

PWD: /Users/jon/.rvm/gems/ruby-2.2.2@rhodes-5.0.30-sp3-57e9d466-watusi/gems/rhodes-5.0.30

CMD: /Library/Java/Home/bin/javac -g -d /Users/jon/workspace/Sargent/build/android/singer/development/bin/tmp/BonjourBrowser -source 1.6 -target 1.6 -nowarn -encoding latin1 -classpath /Users/jon/sdk/android/sdk/platforms/android-22/android.jar:/Users/jon/sdk/android/sdk/extras/android/support/v4/android-support-v4.jar:/Users/jon/workspace/Sargent/build/android/singer/development/bin/tmp/Rhodes:/Users/jon/workspace/Sargent/build/android/singer/development/bin/target/android/release/extensions/coreapi/android-support-v4.jar:/Users/jon/workspace/Sargent/build/android/singer/development/bin/target/android/release/extensions/coreapi/coreapi.jar:/Users/jon/workspace/Sargent/build/android/singer/development/bin/target/android/release/librhodes/Rhodes.jar:/Users/jon/workspace/Sargent/build/android/singer/development/bin/target/android/release/extensions/coreapi/coreapi.jar @/var/folders/qs/mry441454mq56w00y5f59c200000gn/T/BonjourBrowserSRC_build20150426-39991-foco3u

/Users/jon/workspace/Sargent/build/android/singer/development/extensions/BonjourBrowser/ext/platform/android/src/com/rho/bonjourbrowser/BonjourBrowser.java:10: cannot find symbol

symbol  : constructor BonjourBrowserBase()

location: class com.rho.bonjourbrowser.BonjourBrowserBase

  public BonjourBrowser(String id) {

                                   ^

1 error

rake aborted!

Error compiling java code

BonjourBrowser.java

package com.rho.bonjourbrowser;

import java.util.Map;

import com.rhomobile.rhodes.api.IMethodResult;

import com.rhomobile.rhodes.api.MethodResult;

public class BonjourBrowser extends BonjourBrowserBase implements IBonjourBrowser {

    public BonjourBrowser(String id) {

        super(id);

    }

    @Override

    public void calcSumm(int a, int b, IMethodResult result) {

          result.set(a+b);

    }

}

ext/platform/android/ext_java.files

ext/platform/android/generated/src/com/rho/bonjourbrowser/BonjourBrowserBase.java

ext/platform/android/generated/src/com/rho/bonjourbrowser/BonjourBrowserFactorySingleton.java

ext/platform/android/generated/src/com/rho/bonjourbrowser/BonjourBrowserSingletonBase.java

ext/platform/android/generated/src/com/rho/bonjourbrowser/IBonjourBrowser.java

ext/platform/android/generated/src/com/rho/bonjourbrowser/IBonjourBrowserFactory.java

ext/platform/android/generated/src/com/rho/bonjourbrowser/IBonjourBrowserSingleton.java

ext/platform/android/src/com/rho/bonjourbrowser/BonjourBrowser.java

ext/platform/android/src/com/rho/bonjourbrowser/BonjourBrowserFactory.java

ext/platform/android/src/com/rho/bonjourbrowser/BonjourBrowserSingleton.java

I'm afraid I know absolutely nothing about Android development. But I'd have expected the extension to build with the default code.

I guess I am supposed to remove/comment super(id), but that doesn't make a difference.

What am I missing?

Jon Tara
I generated a new app, and

I generated a new app, and then generated a new extension, with same name as mine (was concerned might be issues with upper/lower case extension name, so used same name.

Baffled because it builds just fine. I can't find any difference between the newly-generated API and mine, save for my iOS implementation, and the couple of generated demo methods that I removed.

The file lists are identical.

ext.yml is identical.

Can't seem to find what is different. I guess I will have to move my extension out of the project to a safe place and start over (generate a new extension), then move my XML and my iOS code back in.

Anybody else encounter this?

Also, not sure now why it is that I should remove super(id). I didn't my my test app, and calcSumm() works. Not sure what that is supposed to accomplish, and the documentation doesn't give any reason.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
I made some progress. At

I made some progress. At least it will build now. I figured-out from working with the small default project that I need to override every one of my methods, even if (initially) not implementing. That's not needed in an iOS extension.

Not sure why I got the error message that I did initially, because on the default project, I did get a different error message...

However, I have run-time problems:

From my Settings controller (simple test), My expectation at this point is that I will get no callbacks from my calls to .search() since it is just a stub implementation on Android at this point. But I would have expected to be able to get properties. (Note the {{logInfo}} stuff gets substitute with calls to Rho::Log during build.)

  def bonjour_browser_search

    # Note: default service type is '_http._tcp_.', default domain is '.local'

    # All HTTP servers

    Rho::BonjourBrowser.search({}, lambda do |callback_data|

      {{#logInfo}} "got callback from Rho::BonjourBrowser.search callback_data = #{callback_data.inspect}" {{/logInfo}}

      end # lambda

    )

    # Get two browsers going at once as a test

    meta_browser = Rho::BonjourBrowser.new

      meta_browser.search({serviceType: Rho::BonjourBrowser::SERVICE_TYPE_META_QUERY}, lambda do |callback_data|

        {{#logInfo}} "got callback from (meta_browser) Rho::BonjourBrowser.search callback_data = #{callback_data.inspect}" {{/logInfo}}

      end # lambda

    )

    {{#logInfo}}

      [

        "Rho::BonjourBrowser.serviceType = #{Rho::BonjourBrowser.serviceType.inspect}",

        "Rho::BonjourBrowser.domain = #{Rho::BonjourBrowser.domain.inspect}",

        "Rho::BonjourBrowser.getProperty('serviceType') = #{Rho::BonjourBrowser.getProperty('serviceType').inspect}",

        "Rho::BonjourBrowser.getProperty('domain') = #{Rho::BonjourBrowser.getProperty('domain').inspect}",

        "Rho::BonjourBrowser.getAllProperties = #{Rho::BonjourBrowser.getAllProperties.inspect}",

        "Rho::BonjourBrowser.getProperties(['serviceType', 'domain']) = #{Rho::BonjourBrowser.getProperties(['serviceType', 'domain']).inspect}"

      ]

    {{/logInfo}}

    Rho::BonjourBrowser.getAllProperties( lambda do |p|

      {{#logInfo}}

        "lambda property getter test: #{p.inspect}"

      {{/logInfo}}

    end )

  end

/APP    ( 1812): I 04/27/2015 17:58:27:633 00000714  RhoWebChromeClient| click href =  -- From line 14 of http://127.0.0.1:8080/public/js/silent_post.js?1430169952

I/chromium( 1812): [INFO:CONSOLE(14)] "click href = ", source: http://127.0.0.1:8080/public/js/silent_post.js?1430169952 (14)

I/APP    ( 1812): I 04/27/2015 17:58:27:634 00000742          HttpServer| Process URI: '/app/Settings/bonjour_browser_search'

I/APP    ( 1812): I 04/27/2015 17:58:27:635 00000742                  APP| RHO serve: /app/Settings/bonjour_browser_search

I/APP    ( 1812): E 04/27/2015 17:58:27:635 00000742  BonjourBrowserRUBY| Error setting callback ^^^

I/APP    ( 1812): E 04/27/2015 17:58:27:635 00000742  BonjourBrowserRUBY| Error setting callback ^^^

I/APP    ( 1812): I 04/27/2015 17:58:27:636 00000742  SettingsController| [bonjour_browser_search](52) Rho::BonjourBrowser.serviceType = nil

I/APP    ( 1812): I 04/27/2015 17:58:27:636 00000742  SettingsController| Rho::BonjourBrowser.domain = nil

I/APP    ( 1812): I 04/27/2015 17:58:27:637 00000742  SettingsController| Rho::BonjourBrowser.getProperty('serviceType') = nil

I/APP    ( 1812): I 04/27/2015 17:58:27:637 00000742  SettingsController| Rho::BonjourBrowser.getProperty('domain') = nil

I/APP    ( 1812): I 04/27/2015 17:58:27:637 00000742  SettingsController| Rho::BonjourBrowser.getAllProperties = {"id"=>"SCN1"}

I/APP    ( 1812): I 04/27/2015 17:58:27:637 00000742  SettingsController| Rho::BonjourBrowser.getProperties(['serviceType', 'domain']) = nil

I/APP    ( 1812): E 04/27/2015 17:58:27:637 00000742  BonjourBrowserRUBY| Error setting callback ^^^

I/APP    ( 1812): I 04/27/2015 17:58:27:638 00000742          HttpServer| GC Start.

I/APP    ( 1812): I 04/27/2015 17:58:27:640 00000742          HttpServer| GC End.

My only guess here is that Lambda callbacks do not work for Android?

No, that can't be right, because I use lambda callbacks in some network code, and it work on both iOS and Android.

Any clue what "error setting callback" means?

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
Managed to reproduce the

Managed to reproduce the original error. It came back when I commented-out super(this) in the constructor. Clearly, that's erroneous advice in the documentation. What is actually needed? It doesn't seem it's possible to follow the example given in the documentation and actually wind-up with something working.

Rhomobile | Building a native extension

----

Now open extensions/greeting/ext/platform/android/src/com/rho/greeting/GreetingSingleton.java. This class is declared to implement the IGreetingSingleton interface we just saw in the previous step but it will not compile in its present form. This is an implementation class, which means it was autogenerated the first time but it is now up to you to make the relevant changes to implement the API correctly.

In order to do that:

  • remove the call to super(this) in the constructor
  • remove all existing methods

----

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
Actually, there isn't any

Actually, there isn't any super(this). So, that's erroneous to begin with.

Maybe I commented-out the wrong line. I commented-out in the singleton. I think I need to comment-out in the super(id) in the base under src?

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
Nope that doesn't work either

Nope that doesn't work either. Same error.

The documentation is bogus. My original error was created by following this apparently incorrect advice in the documentation.

Anybody have success creating an Android native extension?

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Pietro Francesc...
Hi Jon,I built a couple of

Hi Jon,

I built a couple of Android native extension some times ago, it was on v4.0 and then I ported them to v4.1. So should be very similar to v5.0 because it's v4.1 that introduced support for multiple architecture on Android (we added Intel in v4.1, previously was only ARM).

Nothing very complicated, is simply a matter of understanding what is what, and with a lot of files having the same name... is not easy at the beginning :-/

I never built an iOS extension more complex than the sample one and it was wayyyy back.

~Pietro

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Mark Nongkhlaw
If I remember correctly,

If I remember correctly, there was a session on building native extensions in last year's Appforum and the presentation slides and sample app were also made available later, but not sure if it was for WM or Android. I will have to search my files, i.e. if it helps.

Plus there was some blog post titled 'Dont fear the natives' or some such in the Rhomobile space in Jive, this is right off my head.

Haven't had time to do a native extension, though, shame on me

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
"Error setting callback"

"Error setting callback" message is found in generated code in the Ruby wrapper. It's an erroneous message, as far as I can tell. It's not an error. It just means no callback was found. Well, when you have an API with optional callback, it just might be that no callback will be found...

I think maybe it is working as it should. I don't get back any properties to my property queries, because my 'start' method takes a hash as the first parameter and is supposed to merge the hash contents into properties. I haven't done that yet (for Android).

At least it builds, and I do get a lonely ID property for the default instance...

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Anonymous (not verified)
Yes, we did cover that at

Yes, we did cover that at AppForum 2014. Links to all the presentations are on the right-hand side of the page. There are two on "Using Native Extensions" including one with sample code.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
Thanks for the link

Thanks for the link.

Unfortunately, those two sessions were both about creating WM extensions. I'm trying to create an Android extension.

It's humbling to be stumbling-around on a platform you are unfamiliar with. I can write iOS extensions till the cows come home! But I'm pretty lost on Android.

It doesn't help that I've written a pretty fully-featured extension for iOS. The examples I've seen are all rather basic. I'm trying to create a "poster child" extension with all of the bells and whistles.That is, it has:

- properties

- constants

- a method that accepts (hopefully, an optional...) properties hash that get merged with existing properties

- a method with an optional callback (the same as the one above)

- asynchronous callbacks

- factory, with a default instance

What I am finding, I am afraid, is that not all the bells and whistles work on every platform.

I've had to go poking-around through the Rhodes source code for example code, and then figure out which APIs follow best practices, and which ones kludge it up in one way or another. I only find bits and pieces in different APIs, since no one API seems to fully embrace the 4.x+ API principles. Many of the Rhodes APIs collapse the implementation and base code together, which, of course, is a sensible optimization for core APIs, but makes it difficult to relate that code to how one might do it in a generated extension.

I seem to be having trouble here with an optional callback. I'm not really sure how to handle that. In my iOS extension, in order to have an optional callback as the last parameter, I had to make the first parameter (an properties hash) mandatory. I haven't yet worked-out the code to allow the first parameter to be omitted. No big deal, for now I pass {} if I don't want to set any properties.

It works fine in iOS. But for Android, my implementation of the method that has the optional callback ("browse") isn't even being called. The C ruby adapter code is giving an error message as shown above:

  1. I/APP    ( 1812): E 04/27/2015 17:58:27:635 00000742  BonjourBrowserRUBY| Error setting callback ^^^ 

And then never calls my implementation code. What is strange is that I DID supply a callback! I think that in the case of Android that the generated code assumes that the optional callback will be in the first parameter. maybe android C adapter code does some checking that iOS C adapter code does not. I will try making it a mandatory callback.

My other methods (calcSumm() example and stopBrowsing() ) are being called. Finger seems to point at optional callback.

Any help appreciated. I'll be open-sourcing this once I complete the Android implementation. (I have no interest in WM, but if somebody else wants to implement a bonjour browser for WM,..) That gives the community two useful things:

- A Bonjour Browser extension

- An example extension that exercises all of the features of Factory-based extensions

I've been working on this for now inside an app I am working on. But if anyone is interested in helping, I think the easiest thing would be for me to make a minimal sample app with the extension built-in.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
No luck with mandatory

No luck with mandatory callback. Same thing.

Pulling my hair out here, guessing at it.

Android doesn't tolerate an empty hash as a parameter? (first parameter)

Rhodes doesn't support lambda callback on Android?

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
I changed my 'search' method

I changed my 'search' method so that it takes NO parameters. It still isn't called, even though my other methods are called.

I am still getting "Callback has been set ^^^" and "Error setting callback ^^^", even though the method does NOT take a callback now. It is showing 1 passed argument, even though I haven't passed any.

As well, properties seem completely broken in Android. I have properties declared in the XML, and they all have default values. When I try to retrieve properties, on Android, I only get ID. Nothing else. Works fine in iOS, and there was no code I had to write myself in order to have properties work.

Are there any examples of a functional Android 4.x-style extension I can follow?

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
Properties seem completely
Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
I've come to the conclusion

I've come to the conclusion that the common API for Android has some serious problems, and it just isn't practical to create Android extensions at this time, at least not for common API. Looking at master, I get the impression that internal developers are also struggling with similar issues.

Can we get some sort of a status update on Android common API - what works, what doesn't work, so that we don't waste our time building extensions that can't possibly work?

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Mark Nongkhlaw
>Can we get some sort of a

>Can we get some sort of a status update on Android common API - what works, what doesn't …

+1

Jon, this might sound like going back, plus its just a hunch (it might work), but have you tried with v2.2 instead ?

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Jon Tara
I assume you mean with a V2.2

I assume you mean with a V2.2-style API, not actually with V2.2!

I'm going to make a new post. It looks like common API is pretty broken for Android.

I think it can be worked-around.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Mark Nongkhlaw
>I assume you mean with a V2

>I assume you mean with a V2.2-style API, not actually with V2.2!

Well, you can try both, I see no harm in it.

BTW, I'm using email & a WM 6 consumer device to send this response

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Mark Nongkhlaw
The docs for 2.2 here : docs

The docs for 2.2 here : docs.rhomobile.com/en/2.2.0/rhodes/extensions seem to be much clearer to me, and there was an old weekly Rhomobile webcast done by Brian which explained and showcased the Accelerometer & 3D Graphics native extension. I could email that if you're interested.

Unfortunately, the explanation in above docs & video are very detailed for iOS only, but I'm sure you'll be able to deduce what needs to be done for Android.

I'm not sure if the process detailed above would apply to 5.3.x though. Nevertheless, I don't believe the latest is the greatest. It depends on what you need to do, what features you want.

Native extensions would require knowledge of Java, C, C++, maybe objective C for iOS, maybe VB.NET/C# for WP, something which I do not have and therefore would not attempt to do.

HTH

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Pietro Francesc...
Hi Jon and Mark,I'll try to

Hi Jon and Mark,

I'll try to see if I can get someone from the team involved in this discussion.

~Pietro

Vote: 
Vote up!
Vote down!

Points: 1

You voted ‘up’


Jon Tara
Appreciate any input.This is

Appreciate any input.

This is probably a better place for it, as now I've gotten past the problem first described here, and found a few others:

We really need some attention to documentation and bug-fixes for Android extensions.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Log in to post comments