Total Noob to gwt/gson in eclipse, error: "Unable to invoke no-args constructor for class"

gwt
17,925

You need to add a no-args constructor such as:

public class Tweet implements Serializable{

  public Tweet(){
  }

}

EDIT

You will also need one here too

private class SearchResponse {

  public SearchResponse(){
  }
  public List<Tweet> results;
}

to deal with your error java.lang.RuntimeException: Unable to invoke no-args constructor for class

A user defined class is serializable if:

  1. the class is assignable to IsSerializable or java.io.Serializable, either because it implements one of these interfaces, or because it is derived from a superclass that implements one of these interfaces.

  2. all the class’s non-final, non-transient instance fields are serializable

  3. the class has a public default (zero argument) constructor

above is from this tutorial

Share:
17,925
brl8
Author by

brl8

Updated on June 11, 2022

Comments

  • brl8
    brl8 almost 2 years

    I'm playing around with this Google Web toolkit/GSON example that gets data from twitter.

    Everything is compiling just fine, but when I debug as Web Application, everything loads just fine, but when I click the "search" button I get the following error:

    SEVERE: javax.servlet.ServletContext log: Exception while dispatching incoming RPC call com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract java.util.List com.google.gwt.twittersearch.client.TwitterService.searchTweets(java.lang.String) throws java.io.IOException,java.lang.IllegalArgumentException' threw an unexpected exception: java.lang.RuntimeException: Unable to invoke no-args constructor for class com.google.gwt.twittersearch.server.TwitterServiceImpl$SearchResponse. Register an InstanceCreator with Gson for this type may fix this problem. at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:385) at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:588) at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:208) at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248) at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166) at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:35) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:60) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:94) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:370) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at org.mortbay.jetty.Server.handle(Server.java:326) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409) at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582) Caused by: java.lang.RuntimeException: Unable to invoke no-args constructor for class com.google.gwt.twittersearch.server.TwitterServiceImpl$SearchResponse. Register an InstanceCreator with Gson for this type may fix this problem. at com.google.gson.internal.ConstructorConstructor$8.construct(ConstructorConstructor.java:167) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:162) at com.google.gson.Gson.fromJson(Gson.java:795) at com.google.gson.Gson.fromJson(Gson.java:734) at com.google.gwt.twittersearch.server.TwitterServiceImpl.parseSearchResponse(TwitterServiceImpl.java:80) at com.google.gwt.twittersearch.server.TwitterServiceImpl.searchTweets(TwitterServiceImpl.java:35) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:115) at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:569) ... 34 more Caused by: java.lang.UnsupportedOperationException: Cannot allocate class com.google.gwt.twittersearch.server.TwitterServiceImpl$SearchResponse at com.google.gson.internal.UnsafeAllocator$4.newInstance(UnsafeAllocator.java:100) at com.google.gson.internal.ConstructorConstructor$8.construct(ConstructorConstructor.java:164) ... 45 more

    Here is the TwitterServiceImpl code:

    package com.google.gwt.twittersearch.server;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.Reader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLEncoder;
    import java.util.List;
    
    import com.google.gwt.twittersearch.client.Tweet;
    import com.google.gwt.twittersearch.client.TwitterService;
    import com.google.gson.Gson;
    import com.google.gwt.user.server.rpc.RemoteServiceServlet;
    
    @SuppressWarnings("serial") 
    public class TwitterServiceImpl extends RemoteServiceServlet implements
            TwitterService {
    
        @Override
        public List<Tweet> searchTweets(String query) throws IllegalArgumentException, IOException {
              query = query.trim();
              if (query.isEmpty()) {
                throw new IllegalArgumentException("No search query specified.");
              }
    
              // see: https://dev.twitter.com/docs/api/1/get/search
              String q = URLEncoder.encode(query, "UTF-8");
              URL url = new URL("http://search.twitter.com/search.json?q=" + q);
              HttpURLConnection connection = (HttpURLConnection) url.openConnection();
              InputStream response = null;
              try {
                response = connection.getInputStream();
                return parseSearchResponse(response);
              } finally {
                if (response != null) {
                  response.close();
                }
              }
        }
    
        @Override
        public String getPrivacyPolicy() throws IOException {
            // see: https://dev.twitter.com/docs/api/1/get/legal/privacy
            URL url = new URL("https://api.twitter.com/1/legal/privacy.json");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            InputStream response = null;
            try {
                response = connection.getInputStream();
                return parsePolicyResponse(response);
            } finally {
                if (response != null) {
                    response.close();
                }
            }
        }
    
        /**
         * Parses the privacy policy response returned from the Twitter API.
         * @param response the response
         * @return the privacy policy
         * @throws IOException if there was a problem reading the response
         */
        private String parsePolicyResponse(InputStream response) throws IOException {
            Reader reader = new InputStreamReader(response);
            PrivacyPolicyResponse privacyPolicyResponse = new Gson().fromJson(reader, PrivacyPolicyResponse.class);
            return privacyPolicyResponse.privacy;
        }
    
        /**
         * Parses the search response returned from the Twitter API.
         * @param response the response
         * @return the search results
         * @throws IOException if there was a problem reading the response
         */
    
        private List<Tweet> parseSearchResponse(InputStream response) throws IOException {
              Reader reader = new InputStreamReader(response);
              SearchResponse searchResponse = new Gson().fromJson(reader, SearchResponse.class);
              return searchResponse.results;
            }
    
        private class PrivacyPolicyResponse {
        public String privacy;
        }
    
    
        private class SearchResponse {
          public List<Tweet> results;
        }
    
    }
    

    Here is the entry point code:

        package com.google.gwt.twittersearch.client;
    
    import java.util.List;
    import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
    import com.google.gwt.core.client.EntryPoint;
    import com.google.gwt.core.client.GWT;
    import com.google.gwt.event.dom.client.ClickEvent;
    import com.google.gwt.event.dom.client.ClickHandler;
    import com.google.gwt.user.client.rpc.AsyncCallback;
    import com.google.gwt.user.client.ui.Button;
    import com.google.gwt.user.client.ui.HTML;
    import com.google.gwt.user.client.ui.HorizontalPanel;
    import com.google.gwt.user.client.ui.Image;
    import com.google.gwt.user.client.ui.Label;
    import com.google.gwt.user.client.ui.Panel;
    import com.google.gwt.user.client.ui.RootPanel;
    import com.google.gwt.user.client.ui.TextBox;
    import com.google.gwt.user.client.ui.VerticalPanel;
    
    /**
     * Entry point classes define <code>onModuleLoad()</code>.
     */
    public class TwitterSearch implements EntryPoint {
      private Button privacyPolicyButton;
      private Button searchButton;
      private TextBox searchQueryTextBox;
      private Panel resultsPanel;
      private Label errorLabel;
      private Image loadingImage;
      private final TwitterServiceAsync service = GWT.create(TwitterService.class);
    
    /**
     * This is the entry point method.
     */
    public void onModuleLoad() {
        createWidgets();
        layoutWidgets();
    
    }
    
    private void createWidgets() {
        searchQueryTextBox = new TextBox();
    
        searchButton = new Button("Search");
        searchButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                setLoading(true);
                String query = searchQueryTextBox.getText();
                service.searchTweets(query, new AsyncCallback<List<Tweet>>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        errorLabel.setText(caught.getMessage());
                        errorLabel.setVisible(true);
                        setLoading(false);
                    }
    
                    @Override
                    public void onSuccess(List<Tweet> result) {
                        resultsPanel.clear();
                        for (Tweet tweet : result) {
                            SafeHtmlBuilder builder = new SafeHtmlBuilder();
                            builder.appendHtmlConstant("<b>User: </b>");
                            builder.appendEscaped(tweet.getFrom_user());
                            builder.appendHtmlConstant("<br /><b>Created: </b>");
                            builder.appendEscaped(tweet.getCreated_at());
                            builder.appendHtmlConstant("<br /><b>Tweet: </b>");
                            builder.appendEscaped(tweet.getText());
                            builder.appendHtmlConstant("<br /><br />");
                            resultsPanel.add(new HTML(builder.toSafeHtml()));
                        }
                        setLoading(false);
                    }
                });
            }
        });
    
        privacyPolicyButton = new Button("Privacy Policy");
        privacyPolicyButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                setLoading(true);
                service.getPrivacyPolicy(new AsyncCallback<String>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        errorLabel.setText(caught.getMessage());
                        errorLabel.setVisible(true);
                        setLoading(false);
                    }
    
                    @Override
                    public void onSuccess(String result) {
                        resultsPanel.clear();
    
                        // convert newlines to <br />
                        SafeHtmlBuilder builder = new SafeHtmlBuilder();
                        builder.appendEscapedLines(result);
    
                        resultsPanel.add(new HTML(builder.toSafeHtml()));
    
                        setLoading(false);
                    }
                });
            }
        });
    
        resultsPanel = new VerticalPanel();
    
        errorLabel = new Label();
        errorLabel.addStyleName("errorLabel");
        errorLabel.setVisible(false);
    
        //image from http://loadinfo.net/
        loadingImage = new Image("loading.gif");
        loadingImage.setVisible(false);
    }
    
    private void layoutWidgets() {
        Panel panel = new VerticalPanel();
    
        panel.add(errorLabel);
    
        Panel horizPanel = new HorizontalPanel();
        horizPanel.add(searchQueryTextBox);
        horizPanel.add(searchButton);
        horizPanel.add(privacyPolicyButton);
        horizPanel.add(loadingImage);
        panel.add(horizPanel);
    
        panel.add(resultsPanel);
    
        RootPanel.get().add(panel);
    }
    
    /**
     * Updates the UI for when a RPC call is made.
     * @param loading true if an RPC call is being sent, false if not
     */
    private void setLoading(boolean loading) {
        if (loading) {
            errorLabel.setVisible(false);
        }
        searchQueryTextBox.setEnabled(!loading);
        searchButton.setEnabled(!loading);
        privacyPolicyButton.setEnabled(!loading);
        loadingImage.setVisible(loading);
    }
    }
    

    Here is the tweet code:

        package com.google.gwt.twittersearch.client;
    
    import java.io.Serializable;
    
    @SuppressWarnings("serial")
    public class Tweet implements Serializable{
    private String id;
      private String from_user;
      private String created_at;
      private String text;
    
      public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getFrom_user() {
            return from_user;
        }
    
        public void setFrom_user(String from_user) {
            this.from_user = from_user;
        }
    
        public String getCreated_at() {
            return created_at;
        }
    
        public void setCreated_at(String created_at) {
            this.created_at = created_at;
        }
    
        public String getText() {
            return text;
        }
    
        public void setText(String text) {
            this.text = text;
        }
    
    
    }
    

    Any insight into this error or where I might go from here would be greatly appreciated!

    Thanks, brl

  • brl8
    brl8 over 11 years
    Hoepfully I did not do something stupid but I tried this and I'm still getting the same error. I tried this: public class Tweet implements Serializable{ private String id; private String from_user; private String created_at; private String text; /** public Tweet(String twit_id, String twit_user, String twit_created, String twit_text){ * id = twit_id; * from_user = twit_user; * created_at = twit_created; * text = twit_text; } */ public Tweet() { } public String getId() { return id; }and I also tried it with the commented part uncommented
  • user1258245
    user1258245 over 11 years
    @user1628648 see my edited comments. You also need a no-args constructor for SearchResponse.