Slice Android Studio

nerosneros Mauris DupondOrganization: CERIProject: middlewareMember

Could you explain how include the slice2java generated classes in Android Studio Project

Thanks for your help.

here is my build.gradle :

buildscript {

repositories {
    google()
    jcenter()

    mavenCentral()
    maven {
        url "https://plugins.gradle.org/m2/"
    }
}
dependencies {
    classpath 'com.android.tools.build:gradle:3.1.1'
    classpath "gradle.plugin.com.zeroc.gradle.ice-builder:slice:1.4.5"


    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}

}

apply plugin: 'java'
apply plugin: 'slice'
slice {
java {
srcDir = '.'
}
}
dependencies {
compile 'com.zeroc:ice:3.7.0'
}

allprojects {
repositories {
google()
jcenter()
}
}

Best Answer

  • xdmxdm La Coruña, SpainJose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice Developer ZeroC Staff
    Accepted Answer

    Android studio doesn't resolve Ice.Communicator

    Ice.Communicator is part of ice-compat.jar

    java.lang.ClassCastException: Ice.ObjectPrxHelperBase cannot be cast to com.zeroc.Ice.ObjectPrx

    Seems to me you are mixing the code generated with no compat with the compat jars

            MP3.ClientMetaServeurPrx printer = MP3.ClientMetaServeurPrx.checkedCast(base);
    

    With the compat mapping this should be

            MP3.ClientMetaServeurPrx printer = MP3.ClientMetaServeurPrxHelper.checkedCast(base);
    

    For example with the compat mapping the checkedCast operation is provided by the helper class and not by the proxy interface.

    slice {
    java {
    srcDir = '.'
    compat = true
    }
    }
    

    That is probably the cause, compat is a property of the slice plug-in object not part of the java source set, try:

    slice.compat = true
    
    slice {
      java {
        srcDir = '.'
      }
    }
    

Answers

  • xdmxdm La Coruña, SpainJose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice DeveloperAdministrators, ZeroC Staff ZeroC Staff

    The buildscript part seems correct, but the project setup seems not.

    Not need to apply Java plug-in on Android, the compile dependencies are not longer used in android it is now implementation.

    I just tested with Android Studio 3.1.2, something along this lines should work for your project build.gradle

    apply plugin: 'com.android.application'
    apply plugin: 'com.zeroc.gradle.ice-builder.slice'
    
    slice.output = file("${project.buildDir}/generated/source/ice")
    
    android {
        compileSdkVersion 26
        defaultConfig {
            applicationId "minimal"
            minSdkVersion 25
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    }
    
    dependencies {
        implementation fileTree(include: ['*.jar'], dir: 'libs')
        implementation 'com.android.support:appcompat-v7:26.1.0'
        implementation 'com.android.support.constraint:constraint-layout:1.1.0'
        implementation 'com.android.support:design:26.1.0'
        implementation 'com.zeroc:ice:3.7.1'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    }
    

    You are at-least missing the slice.output setting and the implementation 'com.zeroc:ice:3.7.1' you should also use the full name to apply the slice plug-in apply plugin: 'com.zeroc.gradle.ice-builder.slice' and do not apply Java plug-in in android projects.

    Cheers,
    José

  • nerosneros Mauris DupondOrganization: CERIProject: middlewareMember
    edited May 2018

    Thanks for reply, I have this errors with this build.gradle

  • xdmxdm La Coruña, SpainJose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice DeveloperAdministrators, ZeroC Staff ZeroC Staff

    This seems unrelated to the Ice builder, from your log:

    Caused by: org.gradle.api.plugins.UnknownPluginException: Plugin with id 'com.android.application' not found.
    

    Seems like your android project is not correctly setup, I will suggest that you try to start by creating a fresh android project then modify it to include the builder should be simpler.

  • nerosneros Mauris DupondOrganization: CERIProject: middlewareMember

    // Top-level build file where you can add configuration options common to all sub-projects/modules.

    buildscript {

    repositories {
        google()
        jcenter()
        mavenCentral()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.1'
        classpath "gradle.plugin.com.zeroc.gradle.ice-builder:slice:1.4.5"
    
    
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
    

    }

    apply plugin: 'java'
    apply plugin: 'slice'
    slice {
    java {
    srcDir = '.'
    }
    }
    dependencies {
    compile 'com.zeroc:ice:3.7.0'
    }
    allprojects {
    repositories {
    google()
    jcenter()
    }
    }

    Error:Static interface methods are only supported starting with Android N (--min-api 24): void com.zeroc.Ice.Object._iceCheckMode(com.zeroc.Ice.OperationMode, com.zeroc.Ice.OperationMode)
    Error:com.android.builder.dexing.DexArchiveBuilderException: Failed to process /home/user/.gradle/caches/modules-2/files-2.1/com.zeroc/ice/3.7.0/6680e137309ee807f890a15aa39f7dd612477fe8/ice-3.7.0.jar
    Error:com.android.builder.dexing.DexArchiveBuilderException: Error while dexing.
    Error:com.android.tools.r8.CompilationFailedException: Compilation failed to complete
    Error:com.android.tools.r8.utils.AbortException

  • nerosneros Mauris DupondOrganization: CERIProject: middlewareMember

    Android Studio can see slice generated package and run emulator, but I have this errors when I lunch the ice client :

    com.zeroc.Ice.SocketException
        error = 0
        at com.zeroc.IceInternal.OutgoingAsync.waitForResponseOrUserEx(OutgoingAsync.java:146)
        at com.zeroc.IceInternal.OutgoingAsync.waitForResponse(OutgoingAsync.java:118)
        at com.zeroc.Ice._ObjectPrxI.ice_isA(_ObjectPrxI.java:36)
        at com.zeroc.Ice.ObjectPrx$$CC._checkedCast$$STATIC$$(Unknown Source:862)
        at com.zeroc.Ice.ObjectPrx$$CC._checkedCast$$STATIC$$(Unknown Source:824)
        at MP3.ClientMetaServeurPrx$$CC.checkedCast$$STATIC$$(Unknown Source:269)
        at m1.tp1.tp1.ClientServeur.<init>(ClientServeur.java:20)
        at m1.tp1.tp1.ListeMorceaux$1.onClick(ListeMorceaux.java:30)
        at android.view.View.performClick(View.java:6294)
        at android.view.View$PerformClick.run(View.java:24770)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: java.net.SocketException: Permission denied
        at sun.nio.ch.Net.socket0(Native Method)
        at sun.nio.ch.Net.socket(Net.java:420)
        at sun.nio.ch.Net.socket(Net.java:413)
        at sun.nio.ch.SocketChannelImpl.<init>(SocketChannelImpl.java:128)
        at sun.nio.ch.SelectorProviderImpl.openSocketChannel(SelectorProviderImpl.java:60)
        at java.nio.channels.SocketChannel.open(SocketChannel.java:145)
        at com.zeroc.IceInternal.Network.createTcpSocket(Network.java:146)
        at com.zeroc.IceInternal.StreamSocket.<init>(StreamSocket.java:22)
        at com.zeroc.IceInternal.TcpConnector.connect(TcpConnector.java:17)
        at com.zeroc.IceInternal.OutgoingConnectionFactory$ConnectCallback.nextConnector(OutgoingConnectionFactory.java:1087)
        at com.zeroc.IceInternal.OutgoingConnectionFactory$ConnectCallback.access$100(OutgoingConnectionFactory.java:852)
        at com.zeroc.IceInternal.OutgoingConnectionFactory.getConnection(OutgoingConnectionFactory.java:553)
        at com.zeroc.IceInternal.OutgoingConnectionFactory.access$800(OutgoingConnectionFactory.java:15)
        at com.zeroc.IceInternal.OutgoingConnectionFactory$ConnectCallback.getConnection(OutgoingConnectionFactory.java:1032)
        at com.zeroc.IceInternal.OutgoingConnectionFactory$ConnectCallback.connectors(OutgoingConnectionFactory.java:916)
        at com.zeroc.IceInternal.EndpointHostResolver.resolve(EndpointHostResolver.java:52)
        at com.zeroc.IceInternal.ProtocolInstance.resolve(ProtocolInstance.java:109)
        at com.zeroc.IceInternal.IPEndpointI.connectors_async(IPEndpointI.java:114)
        at com.zeroc.IceInternal.OutgoingConnectionFactory$ConnectCallback.nextEndpoint(OutgoingConnectionFactory.java:1014)
        at com.zeroc.IceInternal.OutgoingConnectionFactory$ConnectCallback.getConnectors(OutgoingConnectionFactory.java:1004)
        at com.zeroc.IceInternal.OutgoingConnectionFactory$ConnectCallback.access$000(OutgoingConnectionFactory.java:852)
        at com.zeroc.IceInternal.OutgoingConnectionFactory.create(OutgoingConnectionFactory.java:209)
        at com.zeroc.IceInternal.RoutableReference.createConnection(RoutableReference.java:838)
        at com.zeroc.IceInternal.RoutableReference.getConnectionNoRouterInfo(RoutableReference.java:564)
        at com.zeroc.IceInternal.RoutableReference.getConnection(RoutableReference.java:555)
        at com.zeroc.IceInternal.RequestHandlerFactory$1.call(RequestHandlerFactory.java:66)
        at com.zeroc.IceInternal.RequestHandlerFactory$1.call(RequestHandlerFactory.java:62)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    
  • xdmxdm La Coruña, SpainJose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice DeveloperAdministrators, ZeroC Staff ZeroC Staff

    The JavaMapping requires Android 7 (API24) and Source Compatibility / Language Compatibility 1.8

    If you need to target an older API you can use the JavaCompat mapping you should use ice-compat-3.7.1.jar instead of ice-3.7.1.jar

    You also need to configure the slice plugin to use the compat mapping by setting

    slice.compat = true
    
  • nerosneros Mauris DupondOrganization: CERIProject: middlewareMember

    Thanks, But I have a big problem : I use serialized object to String in order to exchange data between Android Ice Client and Linux Ubuntu Ice Server

    But when the Server try to convert String to object, there is an error : java.io.StreamCorruptedException: invalid stream header: EFBFBDEF

    Code used to serialize :

                 try {
                     ByteArrayOutputStream bo = new ByteArrayOutputStream();
                     ObjectOutputStream so = new ObjectOutputStream(bo);
                     so.writeObject(morceau);
                     so.flush();
    
                     return ((String) bo.toString());
    
                 } catch (Exception e) {
                     System.out.println(e);
                 }
    

    Unserialize :

         try {
    
             byte b[] = morceauSerialize.getBytes(); 
             ByteArrayInputStream bi = new ByteArrayInputStream(b);
             ObjectInputStream si = new ObjectInputStream(bi);
             Morceau morceau = (Morceau) si.readObject();
             morceau.setId((long) this.listeMorceaux.size());
             System.out.println("Titre morceau ajoute " + morceau.getTitre());
    
    
    
    
         } catch (Exception e) {
             System.out.println(e);
         }
    
  • xdmxdm La Coruña, SpainJose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice DeveloperAdministrators, ZeroC Staff ZeroC Staff

    You should review the serialize demo for the proper way to do that https://github.com/zeroc-ice/ice-demos/tree/master/java/Ice/serialize

  • nerosneros Mauris DupondOrganization: CERIProject: middlewareMember
    edited May 2018

    Thanks.

    In this demo. the java class to serialize is seen as a byte sequence but my java class has attributes and methods.

    Here is my Morceau class :

    import java.io.Serializable;

    public class Morceau implements java.io.Serializable {

    private String titre;
    
    private String interprete;
    
    private String genre;
    
    private String url;
    
    private long id;
    
    
    public Morceau(String titre, String interprete, String genre, String url, long id) {
    
        this.setTitre(titre);
    
        this.setInterprete(interprete);
    
        this.setGenre(genre);
    
        this.setURL(url);
    
        this.setId(id);
    }
    
    public Morceau() {
    
    }
    
    public String getTitre() {
        return titre;
    }
    
    public void setTitre(String titre) {
        this.titre = titre;
    }
    
    public String getInterprete() {
        return interprete;
    }
    
    public void setInterprete(String interprete) {
        this.interprete = interprete;
    }
    
    public String getGenre() {
        return genre;
    }
    
    public void setGenre(String genre) {
        this.genre = genre;
    }
    
    public String getURL() {
        return url;
    }
    
    public void setURL(String cheminFichier) {
        this.url = cheminFichier;
    }
    
    public long getId() {
        return id;
    }
    
    public void setId(long id) {
        this.id = id;
    }
    

    }

  • xdmxdm La Coruña, SpainJose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice DeveloperAdministrators, ZeroC Staff ZeroC Staff

    The fact that a class has methods it is irrelevant with respect to serialization. I think this demo does exactly what you need send a java.io.Serializable type over the wire using an operation defined in Slice

    If you review the demo all the serialization and deserialization of the Java objects is automatically handle by Ice when you use the appropriate Slice metadata

    On the client side the application pass an instance of the class MyGreeting to the sendGreeting operation, the Ice run-time serialize the Java object using java.io.Serializable interface and send it over the wire as a Slice sequence of bytes.

    On the server side the Ice run-time reads the sequence of bytes, deserialize the object creating an instance of MyGreeting class and pass it as a parameter to the sendGreeting dispatch method.

    The client and server only deal with the Java type MyGreeting and serialization is automatically handle by Ice run-time.

    Your code to serialize the object does not seems correct specially the toString conversion, this is not the serialized data but a description of the ByteArrayOutputStream object.

    Cheers,
    Jose

  • nerosneros Mauris DupondOrganization: CERIProject: middlewareMember

    Thanks, my method to add an object to the server "works", but I have an error in Android and I can't find why :

    android.os.NetworkOnMainThreadException
    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1450)
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:52)
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
    at sun.nio.ch.IOUtil.write(IOUtil.java:65)
    at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:510)
    at com.zeroc.IceInternal.StreamSocket.write(StreamSocket.java:232)
    at com.zeroc.IceInternal.StreamSocket.write(StreamSocket.java:175)
    at com.zeroc.IceInternal.TcpTransceiver.write(TcpTransceiver.java:57)
    at com.zeroc.Ice.ConnectionI.write(ConnectionI.java:3011)
    at com.zeroc.Ice.ConnectionI.sendMessage(ConnectionI.java:2393)
    at com.zeroc.Ice.ConnectionI.initiateShutdown(ConnectionI.java:2018)
    at com.zeroc.Ice.ConnectionI.setState(ConnectionI.java:1985)
    at com.zeroc.Ice.ConnectionI.setState(ConnectionI.java:1793)
    at com.zeroc.Ice.ConnectionI.destroy(ConnectionI.java:161)
    at com.zeroc.IceInternal.OutgoingConnectionFactory.destroy(OutgoingConnectionFactory.java:68)
    at com.zeroc.IceInternal.Instance.destroy(Instance.java:1418)
    at com.zeroc.Ice.CommunicatorI.close(CommunicatorI.java:18)
    at m1.tp1.Serveur.ClientServeur.ajoutMorceau(ClientServeur.java:34)
    at m1.tp1.Serveur.Ajout.ajouter(Ajout.java:61)
    at m1.tp1.Serveur.Ajout.access$000(Ajout.java:13)
    at m1.tp1.Serveur.Ajout$1.onClick(Ajout.java:44)
    at android.view.View.performClick(View.java:6294)
    at android.view.View$PerformClick.run(View.java:24770)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

  • xdmxdm La Coruña, SpainJose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice DeveloperAdministrators, ZeroC Staff ZeroC Staff

    The problem is that android disallow network activity on the MainThread. Only Ice asynchronous APIs must be used from android MainThread.

    In this case Communicator destroy is executed in main thread and it is causing the problem, there is currently no asynchronous API to destroy the communicator so you should ensure this method is from a separate thread and never from MainThread.

  • nerosneros Mauris DupondOrganization: CERIProject: middlewareMember

    The application run successible with Android device emulator, but I have an java.lang.NoClassDefFoundError: com.zeroc.IceInternal.Instance error with a connected device (Android 6, API 23)

    Gradle config in attachment

  • xdmxdm La Coruña, SpainJose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice DeveloperAdministrators, ZeroC Staff ZeroC Staff

    The Java mapping requires Android 7 Api 24, for previous android versions you can use the Java-Compat mapping

    see supported platforms

  • nerosneros Mauris DupondOrganization: CERIProject: middlewareMember

    The server side is very complexe, I have to make a lots of changes ?

  • xdmxdm La Coruña, SpainJose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice DeveloperAdministrators, ZeroC Staff ZeroC Staff

    You have to use java-compat mapping only for the android application, you can keep using java mapping for the server side.

  • nerosneros Mauris DupondOrganization: CERIProject: middlewareMember

    I can't see the difference for client

    My current client is some functions like this :

        String[] params = null;
    
        try (com.zeroc.Ice.Communicator communicator = com.zeroc.Ice.Util.initialize(params)) {
    
    
            com.zeroc.Ice.ObjectPrx base = communicator.stringToProxy("clientmetaserveur:default -h " + adresseIP + " -p 10045");
            MP3.ClientMetaServeurPrx printer = MP3.ClientMetaServeurPrx.checkedCast(base);
            if (printer == null) {
                throw new Error("Invalid proxy");
            }
    
            Morceau morceau = new Morceau();
    
            morceau.titre = titre;
    
            printer.deleteMorceau(morceau);
    
        }
    

    Could you help me to find what I have to change ?

  • nerosneros Mauris DupondOrganization: CERIProject: middlewareMember

    I have change my gradle with :

    // Top-level build file where you can add configuration options common to all sub-projects/modules.

    buildscript {

    repositories {
        google()
        jcenter()
        mavenCentral()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        classpath "gradle.plugin.com.zeroc.gradle.ice-builder:slice:1.4.5"
    
    
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
    

    }

    apply plugin: 'java'
    apply plugin: 'slice'
    slice {
    java {
    srcDir = '.'
    compat = true
    }
    }
    dependencies {
    compile 'com.zeroc:ice-compat:3.7.0'
    }
    allprojects {
    repositories {
    google()
    jcenter()
    }
    }

    but doesn't works

  • xdmxdm La Coruña, SpainJose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice DeveloperAdministrators, ZeroC Staff ZeroC Staff

    The generated code for java-compat is different as it doesn't depend on new features that are only available with Java 8 and up, for compat mapping the Ice types are in Ice package and not in com.zeroc.Ice.

    Your sample above will look something like this with java-compat mapping

        String[] params = null;
    
        try (Ice.Communicator communicator = Ice.Util.initialize(params)) {
    
    
            com.zeroc.Ice.ObjectPrx base = communicator.stringToProxy("clientmetaserveur:default -h " + adresseIP + " -p 10045");
            MP3.ClientMetaServeurPrx printer = MP3.ClientMetaServeurPrxHelper.checkedCast(base);
            if (printer == null) {
                throw new Error("Invalid proxy");
            }
    
            Morceau morceau = new Morceau();
    
            morceau.titre = titre;
    
            printer.deleteMorceau(morceau);
    
        }
    

    You should review the java-compat mapping documentation for the details

  • nerosneros Mauris DupondOrganization: CERIProject: middlewareMember

    Thnaks, but Android studio doesn't resolve Ice.Communicator

  • nerosneros Mauris DupondOrganization: CERIProject: middlewareMember
       try (Ice.Communicator communicator = Ice.Util.initialize()) {
    
    
            Ice.ObjectPrx base = communicator.stringToProxy("clientmetaserveur:default -h " + adresseIP + " -p 10045");
            MP3.ClientMetaServeurPrx printer = MP3.ClientMetaServeurPrx.checkedCast(base);
            if (printer == null) {
                throw new Error("Invalid proxy");
            }
    
    
    
            listTemp = printer.getListeMorceaux();
    
            printer.dumpReponse();
    
    
        }
    

    java.lang.ClassCastException: Ice.ObjectPrxHelperBase cannot be cast to com.zeroc.Ice.ObjectPrx

  • xdmxdm La Coruña, SpainJose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice DeveloperAdministrators, ZeroC Staff ZeroC Staff
    Accepted Answer

    Android studio doesn't resolve Ice.Communicator

    Ice.Communicator is part of ice-compat.jar

    java.lang.ClassCastException: Ice.ObjectPrxHelperBase cannot be cast to com.zeroc.Ice.ObjectPrx

    Seems to me you are mixing the code generated with no compat with the compat jars

            MP3.ClientMetaServeurPrx printer = MP3.ClientMetaServeurPrx.checkedCast(base);
    

    With the compat mapping this should be

            MP3.ClientMetaServeurPrx printer = MP3.ClientMetaServeurPrxHelper.checkedCast(base);
    

    For example with the compat mapping the checkedCast operation is provided by the helper class and not by the proxy interface.

    slice {
    java {
    srcDir = '.'
    compat = true
    }
    }
    

    That is probably the cause, compat is a property of the slice plug-in object not part of the java source set, try:

    slice.compat = true
    
    slice {
      java {
        srcDir = '.'
      }
    }
    
Sign In or Register to comment.