Externalizables

117 views
Skip to first unread message

Junel Mata

unread,
Jan 6, 2015, 2:08:38 AM1/6/15
to codenameone...@googlegroups.com
How to do it right?

public void start() {
        if(current != null){
            current.show();
            return;
        }
        try {
            Util.register("Mails", Mails.class);
            Externalizable mailraw = WebServiceProxy.getMessage("Mails");
            Mails mail = (Mails)mailraw;
           
            current = new Form("Mails");
            current.addComponent(new Label("ID: "+mail.getMessageID())); <-- the error goes here
            current.addComponent(new Label("From: "+mail.getFrom()));
            current.addComponent(new Label("Subject: "+mail.getSubject()));
            current.addComponent(new Label("Content: "+mail.getContent()));
            current.addComponent(new Label("To: "+mail.getTo()));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        
        
        current.show();
    }


Junel Mata

unread,
Jan 6, 2015, 2:57:45 AM1/6/15
to codenameone...@googlegroups.com
I tried another way and still does not work.

public void start() {
        if(current != null){
            current.show();
            return;
        }
        try {
            Util.register("Mails", Mails.class);
            Externalizable mailraw = WebServiceProxy.getMessage("Mails");
            Storage s = Storage.getInstance();
            s.writeObject("Mails", mailraw);
            Mails mail = (Mails)s.readObject("Mails");           
            
            current = new Form("Mails");
            current.addComponent(new Label("ID: "+mail.getMessageID())); <<-- error points in this line.
            current.addComponent(new Label("From: "+mail.getFrom()));
            current.addComponent(new Label("Subject: "+mail.getSubject()));
            current.addComponent(new Label("Content: "+mail.getContent()));
            current.addComponent(new Label("To: "+mail.getTo()));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
               
        current.show();
    }

here's the stack trace:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.codename1.impl.javase.Executor$1.run(Executor.java:95)
at com.codename1.ui.Display.processSerialCalls(Display.java:1080)
at com.codename1.ui.Display.mainEDTLoop(Display.java:902)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
Caused by: java.lang.NullPointerException
at com.icomm.mails.Mailer.start(Mailer.java:54)
... 9 more
Java Result: 1

Shai Almog

unread,
Jan 6, 2015, 10:08:03 AM1/6/15
to codenameone...@googlegroups.com
You are accessing a null object at line 54. Mails can be null, at least on first invocation.

Junel Mata

unread,
Jan 6, 2015, 8:14:08 PM1/6/15
to codenameone...@googlegroups.com
I tried this but the object still gives null value whenever I try printing it. I tried to look at the network monitor and it gives me the correct response body. What did I miss?

here's my code:
public void start() {
        if(current != null){
            current.show();
            return;
        }
        
            current = new Form("Mails");
            current.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
            
            Util.register("Mails", Mails.class);
                    
            Button press = new Button("Press Me!");
            current.addComponent(press);
            press.addActionListener(new ActionListener(){
                Mails mail;
                public void actionPerformed(ActionEvent evt) {                    
                    try {
                        Mails mailraw = (Mails)WebServiceProxy.getMessage("Mails");
                        mail = mailraw;
                        System.out.print(mailraw);
                        if(mail != null){
                            current.addComponent(new Label("ID: "+mail.getMessageID()));
                            current.addComponent(new Label("From: "+mail.getFrom()));
                            current.addComponent(new Label("Subject: "+mail.getSubject()));
                            current.addComponent(new Label("Content: "+mail.getContent()));
                            current.addComponent(new Label("To: "+mail.getTo()));
                        }
                    } catch (IOException ex) {
                       ex.printStackTrace();
                    }
                     
                }
            });         
            
        current.show();
    }

Junel Mata

unread,
Jan 6, 2015, 9:22:19 PM1/6/15
to codenameone...@googlegroups.com
I tried another but I still get null object.

here's my code:
public void start() {
        if(current != null){
            current.show();
            return;
        }
        
        current = new Form("Mails");
        current.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
            
        Util.register("Mails", Mails.class);
                    
        Button press = new Button("Press Me!");
        current.addComponent(press);
        press.addActionListener(new ActionListener(){
            Mails mail;
            public void actionPerformed(ActionEvent evt) {                    
                try {
                    Mails mailraw = (Mails)WebServiceProxy.getMessage("Mails");
                    Storage s = Storage.getInstance();
                    s.writeObject("Mails", mailraw);
                    mail = (Mails)s.readObject("Mails");
                    System.out.print(mailraw);
                    if(mail != null){
                        current.addComponent(new Label("ID: "+mail.getMessageID()));
                        current.addComponent(new Label("From: "+mail.getFrom()));
                        current.addComponent(new Label("Subject: "+mail.getSubject()));
                        current.addComponent(new Label("Content: "+mail.getContent()));
                        current.addComponent(new Label("To: "+mail.getTo()));
                        current.forceRevalidate();
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }                    
            }
        });   
        current.show();
    }

and here's my object "Mails" class code:
public class Mails implements Externalizable{
    
    private int messageID = 1234;
    private String subject = "Mails";
    private String content = "Example Mails";
    private String from = "jm...@icomm.ph";
    private String to = "june...@gmail.com";
    
    public void init(){
        Util.register("Mails",Mails.class);
    }

    @Override
    public int getVersion() {
        return 1;
    }

    @Override
    public void externalize(DataOutputStream out) throws IOException {
        out.write(messageID);
        Util.writeUTF(subject, out);
        Util.writeUTF(content, out);
        Util.writeUTF(from, out);
        Util.writeUTF(to, out);
    }

    @Override
    public void internalize(int version, DataInputStream in) throws IOException {
        messageID = in.readInt();
        subject = Util.readUTF(in);
        content = Util.readUTF(in);
        from = Util.readUTF(in);
        to = Util.readUTF(in);
    }

    @Override
    public String getObjectId() {
        return "Mails";
    }


    public int getMessageID() {
        return messageID;
    }

 
    public void setMessageID(int messageID) {
        this.messageID = messageID;
    }


    public String getSubject() {
        return subject;
    }


    public void setSubject(String subject) {
        this.subject = subject;
    }


    public String getContent() {
        return content;
    }


    public void setContent(String content) {
        this.content = content;
    }

  
    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }
    
}



On Tuesday, January 6, 2015 11:08:03 PM UTC+8, Shai Almog wrote:

Shai Almog

unread,
Jan 7, 2015, 1:55:12 AM1/7/15
to codenameone...@googlegroups.com
Do you have the exact same class both in the client and on the server?
I explained that you should use init in the MAIN class not in the object itself.

Junel Mata

unread,
Jan 7, 2015, 2:11:35 AM1/7/15
to codenameone...@googlegroups.com
Yes, I copied the Object from my server project to my client project. OK I will remove the init method on the object code. 

Junel Mata

unread,
Jan 7, 2015, 3:31:44 AM1/7/15
to codenameone...@googlegroups.com
This is what I did on my server side code:
public class WebServiceProxyServer {
    public static com.codename1.io.Externalizable getMessage(String ObjectName) {
        Util.register("Mails", Mails.class);
        Mails mail = new Mails();
        mail.setMessageID(123);
        mail.setFrom("exa...@mail.com");
        mail.setSubject("Example");
        mail.setContent("Example Mail");
        mail.setTo("desti...@mail.com");
        return mail;
    }
}

and I already removed the init method from my object code but still didn't work, it still returns null even though the response body from the network monitor has content but not exactly the same as what I set with my code above. What did I miss?

Junel Mata

unread,
Jan 7, 2015, 3:38:29 AM1/7/15
to codenameone...@googlegroups.com
here's the structure of my project
Screenshot from 2015-01-07 16:36:31.png

Housseini Moussa

unread,
Jan 7, 2015, 4:56:39 AM1/7/15
to codenameone...@googlegroups.com
I suggest you to register you mail class in the init method of you main class like in the following code.

 public void init(Object context) {
        try {
            Resources theme = Resources.openLayered("/theme");
            UIManager.getInstance().setThemeProps(theme.getTheme(theme.getThemeResourceNames()[0]));
            Util.register("Mails", Mails.class);
        } catch(IOException e){
            e.printStackTrace();
        }

Junel Mata

unread,
Jan 7, 2015, 7:25:35 PM1/7/15
to codenameone...@googlegroups.com
I already did it but still it does not work.

public void init(Object context) {
        try {
            Util.register("Mails", Mails.class);
            Resources theme = Resources.openLayered("/theme");
            UIManager.getInstance().setThemeProps(theme.getTheme(theme.getThemeResourceNames()[0]));
        } catch(IOException e){
            e.printStackTrace();
        }
    }

--
You received this message because you are subscribed to a topic in the Google Groups "CodenameOne Discussions" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/codenameone-discussions/CrHFdAxz7b0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to codenameone-discu...@googlegroups.com.
Visit this group at http://groups.google.com/group/codenameone-discussions.
To view this discussion on the web visit https://groups.google.com/d/msgid/codenameone-discussions/22f38637-5abc-421e-8b23-e92f29e18c1f%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Junel Mata

unread,
Jan 7, 2015, 10:17:08 PM1/7/15
to codenameone...@googlegroups.com
Whenever I use webservice wizard to create a method that returns Externalizable Object, it generates This code to my WebServiceProxy class:
public class WebServiceProxy {
    private static final String DESTINATION_URL = "http://localhost:8080/cn1proxy";

    private static final WebServiceProxyCall.WSDefinition def_getMails = WebServiceProxyCall.defineWebService(DESTINATION_URL, "getMails", WebServiceProxyCall.TYPE_EXTERNALIABLE);
    public static com.codename1.io.Externalizable getMails() throws IOException {
        return ((Externalizable[])WebServiceProxyCall.invokeWebserviceSync(def_getMails)); <--this line is becomes an error. and after removing the brackets, it compiles without error but seems does not work at all.
    }

    public static void getMailsAsync(Callback<com.codename1.io.Externalizable> returnValueFromMethod) {
        WebServiceProxyCall.invokeWebserviceASync(def_getMails, returnValueFromMethod);
    }

}

Junel Mata

unread,
Jan 7, 2015, 10:28:45 PM1/7/15
to codenameone...@googlegroups.com
Whenever I run my application, the response body returns :Mailsmple  Example Mail  exa...@mail.com  desti...@mail.com instead of Mails 123 Example Example Mail exa...@mail.com desti...@mail.com

Junel Mata

unread,
Jan 7, 2015, 10:51:54 PM1/7/15
to codenameone...@googlegroups.com
I tried using this:
WebServiceProxy.getMailsAsync(new Callback<Externalizable>(){
                            public void onSucess(Externalizable value) {
                                Mails mail = (Mails)value;
                                System.out.print(value);
                                if(mail != null){
                                    current.addComponent(new Label("ID: "+mail.getMessageID()));
                                    current.addComponent(new Label("From: "+mail.getFrom()));
                                    current.addComponent(new Label("Subject: "+mail.getSubject()));
                                    current.addComponent(new Label("Content: "+mail.getContent()));
                                    current.addComponent(new Label("To: "+mail.getTo()));
                                    current.forceRevalidate();
                                }
                            }
                            public void onError(Object sender, Throwable err, int errorCode, String errorMessage) {
                                System.out.println(sender);
                                System.out.println(err);
                                System.out.println(errorCode);
                                System.out.println(errorMessage);
                            }
                        });
but it falls on the onError method with the following details:
sender: com.codename1.io.WebServiceProxyCall$WSConnection@cda2c188
err: java.io.EOFException
errorCode: -1
errorMessage: null

I looked at the network monitor and gives me the response code 200 which means OK. is there any problem with my code?

Shai Almog

unread,
Jan 8, 2015, 1:43:29 AM1/8/15
to codenameone...@googlegroups.com
Did you select returning externalizable or externalizable array?

Junel Mata

unread,
Jan 8, 2015, 2:04:02 AM1/8/15
to codenameone...@googlegroups.com
I selected externalizable it is the last option on return types next to String[]. I didn't see such externalizable array on the wizard.

Shai Almog

unread,
Jan 8, 2015, 12:23:35 PM1/8/15
to codenameone...@googlegroups.com
I suggest you file an issue on the brackets in the generates code. They shouldn't be there.
What are the exceptions with full stacks that you get both on the client and the server?

Junel Mata

unread,
Jan 8, 2015, 6:55:38 PM1/8/15
to codenameone...@googlegroups.com
How can I file an issue about the brackets? I've never tried it. When I run the application and use the sync method, it returns null object and when I use the async method, it goes to the onError method with -1 error code throwing IOExeption. I looked into the logs of my server and it works fine. I also looked in to the network monitor in the simulator and it returns 200 response code which means OK as Steve said before.

On Fri, Jan 9, 2015 at 1:23 AM, Shai Almog <shai....@gmail.com> wrote:
I suggest you file an issue on the brackets in the generates code. They shouldn't be there.
What are the exceptions with full stacks that you get both on the client and the server?

--
You received this message because you are subscribed to a topic in the Google Groups "CodenameOne Discussions" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/codenameone-discussions/CrHFdAxz7b0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to codenameone-discu...@googlegroups.com.
Visit this group at http://groups.google.com/group/codenameone-discussions.

Shai Almog

unread,
Jan 9, 2015, 1:50:35 AM1/9/15
to codenameone...@googlegroups.com
I need the actual stack traces from both consoles.

You can file issues here: https://code.google.com/p/codenameone/issues

Junel Mata

unread,
Jan 9, 2015, 2:31:15 AM1/9/15
to codenameone...@googlegroups.com
I already filed an issue (issue: 1272). That's all the stack trace I think? It always return a null object using the sync method and falls on the on Error method when using the async. Can you try running it in your machine or any other way?

I did this:
public void onError(Object sender, Throwable err, int errorCode, String errorMessage) {
                                System.out.println(sender.toString());
                                System.out.println(err);
                                System.out.println(errorCode);
                                System.out.println(errorMessage);
                            }
and produces this:
com.codename1.io.WebServiceProxyCall$WSConnection@cda2c188
java.io.EOFException
-1
null

Shai Almog

unread,
Jan 9, 2015, 10:48:39 AM1/9/15
to codenameone...@googlegroups.com
That's not a stack trace. Try  something like err.printStackTrace().

Junel Mata

unread,
Jan 11, 2015, 7:17:48 PM1/11/15
to codenameone...@googlegroups.com
this is the stackTrace I get:
java.io.EOFException
at java.io.DataInputStream.readFully(DataInputStream.java:197)
at java.io.DataInputStream.readUTF(DataInputStream.java:609)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at com.codename1.io.Util.readUTF(Util.java:969)
at com.icomm.models.Mails.internalize(Mails.java:43)
at com.codename1.io.Util.readObject(Util.java:624)
at com.codename1.io.WebServiceProxyCall$WSConnection.readResponse(WebServiceProxyCall.java:476)
at com.codename1.io.ConnectionRequest.performOperation(ConnectionRequest.java:422)
at com.codename1.io.NetworkManager$NetworkThread.run(NetworkManager.java:261)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)

Shai Almog

unread,
Jan 12, 2015, 1:34:53 AM1/12/15
to codenameone...@googlegroups.com
You used  out.write(messageID);
Instead of  out.writeInt(messageID);

Junel Mata

unread,
Jan 12, 2015, 2:00:55 AM1/12/15
to codenameone...@googlegroups.com
The method already worked. Thanks allot Shai. Can you notify me if the issue I filed earlier is already fixed.

Junel Mata

unread,
Jan 12, 2015, 2:52:22 AM1/12/15
to codenameone...@googlegroups.com
I tried something different:
public class Mails implements Externalizable{
    
    private int messageID;
    private String subject;
    private String content;
    private String from;
    private String to;
    private Message message; <-- I Added and attribute to my class Mails.

and after running my application, the Message object returns null on the client side. causes a NullPointerException

try {
                            Mails mailraw = (Mails)WebServiceProxy.getMails();
                            Storage s = Storage.getInstance();
                            s.writeObject("Mails", mailraw);
                            mail = (Mails)s.readObject("Mails");
                            if(mail != null){
                                current.addComponent(new Label("ID: "+mail.getMessageID()));
                                current.addComponent(new Label("From: "+mail.getFrom()));
                                current.addComponent(new Label("Subject: "+mail.getSubject()));
                                current.addComponent(new Label("Content: "+mail.getContent()));
                                current.addComponent(new Label("To: "+mail.getTo()));
                                System.out.println(mail.getMessage());
                                Message message = (Message)mail.getMessage(); <-- how I assigned the value to a variable.
                                if(message != null){
                                    current.addComponent(new Label("To: "+message.getName()));
                                }
                                current.forceRevalidate();
                            }
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
is this possible?I have the same Externalizable objects on both sides and registered them using util.register.

Shai Almog

unread,
Jan 12, 2015, 10:30:57 AM1/12/15
to codenameone...@googlegroups.com
I'm totally lost in this thread but from the exception you are getting above it seems the methods do not work.
The issue you filed is related to the code generation bug with the array for which you have a workaround. It seems your externalizable methods don't work.

Junel Mata

unread,
Jan 12, 2015, 7:04:47 PM1/12/15
to codenameone...@googlegroups.com
So you mean that a Externalizable Object within an Externalizale Object cannot be passed from server to client and vice versa?can you guys add an array of Externalizables on the webservice wizard? I pretty sure it would be a very useful tool in development. And also array list as well. Thanks.

On Mon, Jan 12, 2015 at 11:30 PM, Shai Almog <shai....@gmail.com> wrote:
I'm totally lost in this thread but from the exception you are getting above it seems the methods do not work.
The issue you filed is related to the code generation bug with the array for which you have a workaround. It seems your externalizable methods don't work.

--
You received this message because you are subscribed to a topic in the Google Groups "CodenameOne Discussions" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/codenameone-discussions/CrHFdAxz7b0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to codenameone-discu...@googlegroups.com.
Visit this group at http://groups.google.com/group/codenameone-discussions.

Shai Almog

unread,
Jan 13, 2015, 1:57:57 AM1/13/15
to codenameone...@googlegroups.com
No. I mean you have a bug in your write and read methods as I explained above.

Junel Mata

unread,
Jan 13, 2015, 2:22:17 AM1/13/15
to codenameone...@googlegroups.com
I also mean that my first method which passes an Externalizable Object from server to client worked fine. Then I tried another thing which is "passing an Externalizable Object containing a Externalizable Object from server to client". The Object was successfully passed from server to client but the inner Object returns a null value even after setting the value from the server side. Please see the attachments for clarifications.

On Tue, Jan 13, 2015 at 2:57 PM, Shai Almog <shai....@gmail.com> wrote:
No. I mean you have a bug in your write and read methods as I explained above.

--
You received this message because you are subscribed to a topic in the Google Groups "CodenameOne Discussions" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/codenameone-discussions/CrHFdAxz7b0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to codenameone-discu...@googlegroups.com.
Visit this group at http://groups.google.com/group/codenameone-discussions.
attachment.PNG

Shai Almog

unread,
Jan 13, 2015, 10:08:32 AM1/13/15
to codenameone...@googlegroups.com
The stack trace you provided clearly shows that loading the externalizable didn't work.
The code you have above is clearly wrong, its hard to follow if you changed that or not. Either way you should fix the stack.

Junel Mata

unread,
Jan 14, 2015, 9:00:44 PM1/14/15
to codenameone...@googlegroups.com
Is this the correct way on how to read/write Objects containing arrays?
public class Message implements Externalizable{
    
    private String Name[];

    @Override
    public int getVersion() {
        return 1;
    }

    @Override
    public void externalize(DataOutputStream out) throws IOException {
        Util.writeObject(Name, out); <-- I think this makes some problem but I'm not sure.
    }

    @Override
    public void internalize(int version, DataInputStream in) throws IOException {
        Name = (String[])Util.readObject(in); <-- I think this makes some problem but I'm not sure.
    }

    @Override
    public String getObjectId() {
        return "Message";
    }

    /**
     * @return the Name
     */
    public String[] getName() {
        return Name;
    }

    /**
     * @param Name the Name to set
     */
    public void setName(String Name[]) {
        this.Name = Name;
    }
    
    public String getNameOnIndex(int index){
        return this.Name[index];
    }

}
Because when I use writeUTF/readUTF, it makes an error. How can I possibly do this? or some other way to do something like this?

Shai Almog

unread,
Jan 15, 2015, 1:31:24 AM1/15/15
to codenameone...@googlegroups.com
No.
Arrays will always be stored as Object[].
I would recommend this:
if(name == null) {
   
out.writeInt(0);
} else {
   
out.writeInt(name.length);
   
for(String n : name) {
       
Util.writeUTF(n, out);
   
}
}


then in read:
name = new String[in.readInt()];
for(int iter = 0 ; iter < name.length ; iter++) {
    name
[iter] = Util.readUTF(in);
}


Didn't test the code so might have missed something like method argument order etc.

Junel Mata

unread,
Jan 15, 2015, 2:08:55 AM1/15/15
to codenameone...@googlegroups.com
I tried it also but I always got an exception. Then I tried List<String> from Steves' tutorial and it worked allot better. Thanks Shai,

--
You received this message because you are subscribed to a topic in the Google Groups "CodenameOne Discussions" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/codenameone-discussions/CrHFdAxz7b0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to codenameone-discu...@googlegroups.com.
Visit this group at http://groups.google.com/group/codenameone-discussions.
Reply all
Reply to author
Forward
0 new messages