Missing Methods and Classes in Jar after Building Xamarin App - java

As i wanted to develop an App with Estimote Beacons i searched for it and found the Xamarin Component Estimote SDK for Android. However, the Version is outdated so i began to try including the estimote sdk for android on myself. With .aar/.jar Binding.
I saw three Options:
fully compile the library and be able to use it as C# Classes
write a wrapper and only let the wrapper interpret and use those classes.
natively call functions from the Library with JNI
Compiling the whole library did not work due to about 102 Errors while building. Working with metadata.xml did not work although i was able to reduce the amount of Errors to 45.
Natively calling functions with JNI is a pain and no option because the Library is too big.
Writing a wrapper nearly worked
I stripped the classes from the estimotesdk.aar so i have only the classes.jar from the inside.
Wrote a Library as wrapper and put that in another jar:
EstimoteSDK.jar --> ReferenceJar
EstimoteWrapper --> EmbeddedJar
I can build the ClassLibrary Project in Visual Studio without Problems. I can even use the classes from the Wrapper in C#.
But now my Problem is:
MissingMethodException and NoClassDefFoundError during Runtime
I found out the following:
The EstimoteSDK.jar and its Class-Files change after building .
For some reason, the EstimoteSDK.jar is not only copied but also modified and loses some functions and even classes.
Proof (used dex2jar tool to get the jar out of the .dex in the builded apk):
The right class File contains less functions than the right
Now my Question:
how can i prevent Xamarin or any other Component from touching the EstimoteSDK.jar and stripping functions and classes from it ?
Setup:
Visual Studio 2015 Professional
Xamarin.Forms 2.0
Windows 7
Android and iOS-App

So, after posting my question to xamarin forums where someone provided a updated version of estimotesdk ( i did not try that so far) and trying out everything i could imagine i found a solution for me:
I have two Jars (EstimoteSDK and my own written Wrapper). Including them with the correct Build Action did it for me:
EstimoteSDK.jar --> EmbeddedReferenceJar
List item --> EmbeddedJar
So this is the correct way to include a native library which is accessed by a wrapper class.

The magic word could be LinkerPleaseInclude.cs. Add a class that references the class / calls the function. But I don't know if your wrapper is in the way, because you aren't binding the estimote lib in the usual way.
public class LinkerPleaseInclude
{
public void Include(Beaconmanager manager)
{
manager.RegionExitExpiration = 0L;
}
}
btw: there is a crossplatform abstraction for estimote: https://www.nuget.org/packages/Estimotes.Xplat/. But it might use the outdated version you mentioned.
Edit:
metadata.xml for Estimote
<metadata>
<remove-node path="/api/package[#name='com.estimote.sdk.repackaged.okhttp_v2_2_0.com.squareup.okhttp.internal.http']"></remove-node>
<remove-node path="/api/package[#name='com.estimote.sdk.repackaged.gson_v2_3_1.com.google.gson.internal.bind']"></remove-node>
<remove-node path="/api/package[#name='com.estimote.sdk.repackaged.gson_v2_3_1.com.google.gson.internal']"></remove-node>
<remove-node path="/api/package[#name='com.estimote.sdk.repackaged.gson_v2_3_1.com.google.gson']"></remove-node>
<remove-node path="/api/package[#name='com.estimote.sdk.repackaged.okio_v1_3_0.okio']"></remove-node>
<remove-node path="/api/package[#name='com.estimote.sdk.repackaged.maven_v3_3_3']"></remove-node>
<remove-node path="/api/package[#name='com.estimote.sdk.connection.internal.protocols']"></remove-node>
<attr path="/api/package[#name='com.estimote.sdk.connection.settings']/class[#name='Version']/method[#name='compareTo' and count(parameter)=1 and parameter[1][#type='com.estimote.sdk.connection.settings.Version']]/parameter[1]"
name="type">Java.Lang.Object</attr>
<attr path="/api/package[#name='com.estimote.sdk.cloud.internal']/class[#name='ChallengeResponse']/field[#name='challengeResponse']" name="name">ChallangeResponseString</attr>
<attr path="/api/package[#name='com.estimote.sdk.cloud.model.google']/class[#name='Beacons']/field[#name='beacons']" name="name">BeaconList</attr>
<attr path="/api/package[#name='com.estimote.sdk.cloud.model.google']/class[#name='Observations']/field[#name='observations']" name="name">ObservationList</attr>
</metadata>

Related

Codename One: Annotation Processing

I have a Codename One project on Netbeans using their plugin.
Is there a way to make it work? I enabled it in project's settings and still doesn't show in final jar.
The annotations are in the libraries of the project. and I can see it being done in the output:
warning: Supported source version 'RELEASE_6' from annotation processor 'org.netbeans.modules.openide.util.ServiceProviderProcessor' less than -source '1.8'
I used instructions here: https://netbeans.org/kb/docs/java/annotations-lombok.html
Update:
I thought it was clear but seems it's not. All this is using Netbean's Lookup. Let's say I have one jar as project dependency with one interface in it, let's say ITest. Also a class implementing the interface, for example:
#ServiceProvider(service=ITest.class)
public class Test implements ITest{
..
}
So in the Codenamone Project I call it like this:
Lookup.getDefault().lookupAll(ITest.class);
But it come up empty. I know the system works as it does in other projects, just porting it to Codename one. Seems like it is not seeing the annotations in the dependencies.
I don't know if that will work and I'm pretty curious about it myself. Make sure you created a Java 8 version of the project and you are running on top of Java 8 to get started.
In the past things like this were done using bytecode manipulation e.g. see this code from the work done by Steve.

Native Java to Android Java (JsonPath)

I'm converting native Java code to android one.
There is a Android Java code from a native Java as following:
import com.jayway.jsonpath.JsonPath;
...
body = new String(bodyPart);
JsonPath.with(body).getString("psIp");
...
However, there is no with method in Android. How can I convert it?
JsonPath class comes from some library (most likely 'com.jayway.jsonpath:json-path:0.8.1'), which has com.jayway.jsonpathpackage. This class is not present neither in native Java, nor in native Android.
You have a dependency to that library, that has JsonPath class, in your Java project (anyway you added it - either through gradle, maven, or simply by adding a reference to jar file through IDE). If you would add that dependency to your Android project (gradle is preferred for adding dependencies in Android, though you can add it any other way), you will be able to use JsonPath class in your Android code also.

Android/PhoneGap: Using third-party libraries in plugin-development

I'm working on a PhoneGap/Cordova plugin that's supposed to provide a socket for sending and receiving OSC messages (Open Sound Control). For that purpose I'd like to use JavaOSC but I'm uncertain about how to include the library into my project.
I'm using Android Studio and I've basically followed this tutorial to set up my project. First I placed the raw JavaOSC class-files in the same directory as my OSCPlugin.class and placed the import declarations at the to of my OSCPlugin.class:
import com.illposed.osc;
That didn't work.
As a next step I tried to add the library from maven within the project's module settings. I was able to download the jar files from maven and install put them into /platforms/android/libs. Within the settings for the module 'android' I can see that 'Android API 17' is supposed to be used as SDK, including cordova-3.1.0 and com.illposed.osc:javaosc-core:0.2 - both activated. I can see the cordova-3.1.0.jar as well as javaosc-core-0.2.jar, containing com.illposed.osc in the navigator within Android Studio.
However, when trying to compile my project I get:
Gradle: cannot find symbol class osc
triggered from within OSCPlugin.class that contains the above mentioned import declaration
I have very little experience with Java and even less with Android development. But I'd be interested in solving this riddle and get started. I have searched the Java docs but the problem doesn't merely lie within Java but rather within the structure of the Android project.
I'd be thankful if someone could shed some light on this issue. Any hint's highly appreciated!
For one of my Phonegap projects I needed the Apache Commons Net, trying to follow these steps:
...
<source-file src="src/android/xxx.jar" target-dir="libs" framework="true" />
<source-file src="src/android/MyPlugin.java" target-dir="src/com/mypackage" />
...
unfortunately, without success. The trick was to embed the third-party library in another plugin (following the very plugin structure). Having the org.apache.commons.net as a top level directory:
org.apache.commons.net
+src
+android(this is where the .jar is located)
+www (empty, not referencing any .js)
+plugin.xml
For brevity, plugin.xml as follows:
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
id="org.apache.commons.net"
version="0.1.0">
<name>org.apache.commons.net</name>
<description>org.apache.commons.net</description>
<license>Apache License, Version 2.0</license>
<keywords>org.apache.commons.net</keywords>
<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="org.apache.commons.net">
<param name="android-package" value="org.apache.commons.net"/>
</feature>
</config-file>
<source-file src="src/android/commons-net-2.2.jar" target-dir="libs" framework="true" />
</platform>
</plugin>
Assuming the org.apache.commons.net directory is located in your local git repo, adding it to your project is as trivial as:
phonegap local plugin add /path/to/your/org.apache.commons.net
To add external library, basically all you have to do is copy the jar to the /libs folder.
Here you have a bad import in your source.
import is used to import a class by specifying the package name followed by the class name and here you only specify the class name, so the error "cannot find symbol class osc" you are having is because there is no class osc.
You should use either
import com.illposed.osc.*; if you want to import all classes from the package
or add an import for each class from the package that you are going to use.
And if you want make the plugin installable using the CLI or phonegap build, you also have to update plugin.xml to add the copy of the jar file.
ps in case you don't know, you won't be able to use classes from com.illposed.osc.ui as they are using swing and designed for the jvm and not android.

Android Screenshot Plugin Working in Cordova 2.0

I am currently developing an Android app using cordova 2.0. Obviously the plugins.xml has been depreciated and everything is now housed in config.xml. I was just wondering if anyone has managed to get the Phonegap Screenshot plugin working in Eclipse and Cordova 2.0 working on android.
Plugin can be found:
https://github.com/josemando/phonegap-plugins/tree/master/Android/Screenshot
I have added:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
to my Android manifest xml. And made sure that:
<plugin name="Screenshot" value="org.apache.cordova.Screenshot"/>
is added to my config.xml (that now contains all plugin information from plugin.xml)
Screenshot.js is added to the directory:
assets/www/js/
However I am unsure where exactly to place the Screenshot.java file. The example has it in:
src / org / apache / cordova /
However as I did not have this directory I simply placed it in:
src/uk.co..appname1.appname2/
When I did this however it produced errors, the first one being:
The declared package "org.apache.cordova" does not match the expected package "uk.co.mysitename.appname1.appname2" Screenshot.java /Project Name/src/uk/co/mysitename/appname1/appname2line 8 Java Problem
This refers to this line in the Screenshot.js:
package org.apache.cordova;
The two suggested actions to fix this are to:
Move 'Screenshot.java' to package 'org.apache.cordova' (this directory doesn't exsist atm)
Or change package directory to 'uk.co.mysitename.appname1.appname2'
The second error says:
The method run() of type new Runnable(){} must override a superclass method
The suggested action for this being to "remove '#override' annotation"
I have tried to do every possible combination of these however I cannot seem to make progress and get it all to link up. Usually because it thinks that CordovaRef isn't referenced. I am unsure if the plugin even works on Cordova 2.0.0. I have some experience with Phonegap/Cordova but only in ios with Xcode and Objective C plugins. I am new to Java, Eclipse and Android. Any help or clarification on any of these matters would be greatly appreciated.
Answer resolved by:
Phonegap Screenshot plugin in Cordova 2.0.0
Answer/solution provided by Simon MacDonald

Groovy, Netbeans and Java EE

I want to develop a web application (no frameworks) mixing java with groovy. I am using the IDE Netbeans with the plugin.
If I start a new Java SE project and add a groovy class, it works with no problems.. but when I create a new java EE project and add a groovy class it can't compile and shows me the following error:
/home/webcodei/NetBeansProjects/testeGroovyWeb/src/java/pacote/Hello.java:23: cannot find symbol
symbol : class Hroovy
location: class pacote.Hello
Hroovy h = new Hroovy();
/home/webcodei/NetBeansProjects/testeGroovyWeb/src/java/pacote/Hello.java:23: cannot find symbol
symbol : class Hroovy
location: class pacote.Hello
Hroovy h = new Hroovy();
2 errors
/home/webcodei/NetBeansProjects/testeGroovyWeb/nbproject/build-impl.xml:383: The following error occurred while executing this line:
/home/webcodei/NetBeansProjects/testeGroovyWeb/nbproject/build-impl.xml:211: Compile failed; see the compiler error output for details.
FALHA NA CONSTRUÇÃO (tempo total: 0 segundos)
Does anybody have a clue of how do I enable Java EE + Groovy in netbeans?
ps: I know the existence of Grails
ps2: The Groovy jar is in my classpath.
Thank you for all!
It appears that the NetBeans 6.5 Java Webapp project manager does not have the "Enable Groovy" support that is present in the Java App and Java Class library projects.
I can think of two ways you might get around this:
First, you could put your Groovy code and tests in a separate project as a Java Class Library. Then make the Java webapp dependent on the Groovy project. NetBeans will build the dependent project automatically so you'll hardly notice they are in separate projects.
Second, the "Enable Groovy" isn't magic. All it does is write a groovy-build.xml in /nbprojects and modify build-impl.xml to import it. The groovy-build.xml overrides the default "javac" macro to invoke "groovyc" instead. If you're at all handy with Ant, you could copy a groovy-build.xml from a Java Application project and copy it to your Java Web project and then import it from your build.xml (before build-impl.xml is imported). The groovy-build.xml would likely need a few tweaks as some of the properties between a webapp and class library are a little different.
#Dave Smith,
This was exactly what I did. I created one javase project and one webapp and started to compare them. After a few minutes I realised that the only diference was the groovy-build.xml.
So I copied the groovy-build.xml into the dir, and inserted the following lines into my build.xml:
<import file="nbproject/groovy-build.xml"/>
Right before the regular
<import file="nbproject/build-impl.xml"/>
And then called the groovy file to overwrite the -init-macrodef-javac.
<target depends="-groovy-init-macrodef-javac" name="-pre-compile">
</target>
I also needed to change the namespace from the groovy-build.xml to mine ex:
<macrodef name="javac" uri="http://www.netbeans.org/ns/web-project/2">
And inserted the j2ee classpath (${j2ee.platform.classpath}) to the attribute a few lines later:
<attribute default="${javac.classpath}:${j2ee.platform.classpath}" name="classpath"/>
After that the project worked successfully! =D
Thank you for all!

Categories

Resources