JBoss Seam 2.2.0 and Google Web Toolkit (GWT) 2.0.0 support

I should have published this sooner when my colleague (Radovan Sninský, working with me on Java Simon among other things) came with the solution how to call Seam components from GWT 2 (probably in milestone 1 already). GWT 2.0.0 changed some details in its RPC protocol and built-in Seam support for GWT stopped working with errors like this:

2010-02-09  10:28:12,265 ERROR  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/whatever]]  (http-127.0.0.1-8080-1) An IncompatibleRemoteServiceException was  thrown while processing this call.
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException:  Parameter 0 of is of an unknown type 'some.Class/some number'
at  org.jboss.seam.remoting.gwt.GWTService.RPC_decodeRequest(GWTService.java:426)
at  org.jboss.seam.remoting.gwt.GWTService.processCall(GWTService.java:203)
at  org.jboss.seam.remoting.gwt.GWTService$1.process(GWTService.java:120)
at  org.jboss.seam.servlet.ContextualHttpServletRequest.run(ContextualHttpServletRequest.java:53)
at  org.jboss.seam.remoting.gwt.GWTService.getResource(GWTService.java:105)
at  org.jboss.seam.servlet.SeamResourceServlet.service(SeamResourceServlet.java:80)
...
Caused  by: java.lang.ClassNotFoundException: some.Class/number
at  java.lang.Class.forName0(Native Method)
at  java.lang.Class.forName(Class.java:247)
at  org.jboss.seam.remoting.gwt.GWTService.RPC_getClassFromSerializedName(GWTService.java:479)
at  org.jboss.seam.remoting.gwt.GWTService.RPC_decodeRequest(GWTService.java:422)
... 46 more

As GWT 2.0 is fresh it was obviously better to patch Seam. And because GWT calls are processed using awesome Seam Adapters (I really like this concept!) we decided to duplicate the existing Adapter and just rewriting problematic parts. The RPC protocol changes were very subtle but it was big enough to blow out in case of Long types and probably some others too. Radovan then copied a few classes from Seam and added some of his code, fixed some lines and registered his GWT Service adapter on the URL suffix /gwt2. That way the only thing you need to do in your project is:

  • download this ZIP
  • unzip it into your src directory and let it be compiled along with EJB part of your application – if you move classes to another package, fix package declaration as well in all 5 classes
  • change the method in GWT UI part where you retrieve the service point – for example:
SomeServiceAsync svc = GWT.create(SomeService.class);
((ServiceDefTarget) svc).setServiceEntryPoint(GWT.getHostPageBaseURL() + "seam/resource/gwt2");

The important part is “gwt2” at the end instead of “gwt”. If you have your URL in some constant, change it there. Recompile, rebuild, redeploy, restart, try it – it should work now. Of course – if you’re really using GWT 2.0.0. 🙂

Licensing? Well… I guess it is LGPL like the original Seam sources. Hopefully there is no Seam 2.3 with GWT 2 support around the corner (doesn’t seem so) which would render this post useless in a day. 😉

Advertisements

About virgo47
Java Developer by profession in the first place. Gamer and amateur musician. And father too. Naive believer in brighter future. Step by step.

49 Responses to JBoss Seam 2.2.0 and Google Web Toolkit (GWT) 2.0.0 support

  1. Anu Yalamanchili says:

    Thanks a lot nice work.
    any plans to submit a it as a seam patch.

    • virgo47 says:

      No… this way it works with gwt (*/gwt2) and on Seam forums they know very well about this issue… so it’s up to them to implement it. It seems that Seam guys are working on RI of WebBeans now and not Seam itself. I’m sure when they do something new on Seam this GWT integration (or better, because now it’s all too hacky for my taste) will be part of it.

  2. currywurry says:

    Great work , guys! fix works like a charm

  3. ali says:

    Before and after this ‘addition’ I receive the following.. mac 1.6, seam 2.2.0, gwt 2.0.3, jboss 5.1

    This application is out of date, please click the refresh button on your browser. ( Blocked attempt to access interface ‘tr.com.veribank.www.client.VeribankService’, which doesn’t extend RemoteService; this is either misconfiguration or a hack attempt )

    • virgo47 says:

      No idea, honestly. The first part seems just cached older version or so… during development, it may happen when not all parts (on server) are turned around completely (undeploy, deploy after complete clean-build). The part with RemoteService – I see such an error for the first time.

    • Sandy Noa says:

      ali, I’m in the same case,
      how could you solve it ???

  4. ali says:

    i have a real good setup for seam/gwt development with wtp/jboss tools/instantions plugins all playing nicely together.. it is a pity this is a show stopper.. if you can spare some time and have interest in taking a look, i can zip the test project and send it over.. might be something obvious that i missed.. i can offer making it public so others can use it as well and coffee in istanbul.. 🙂

  5. ali says:

    coffee offer still remains valid.. thanks for the code..

  6. Flori says:

    hmm has the team of Seam improved/corrected the gwt2 support now? Nevertheless, thanks for the great fix!! cheers!

  7. Chris says:

    The Seam team hasn’t given a crap about Seam 2 in some time now (read almost a year). They’re completely focused on Seam 3/CDI or whatever you want to call it. Too bad they still only have a Seam 3 in “alpha”; meanwhile, hard won Seam 2 battles are being lost due to the Seam team’s lack of interest in the product they developed.

  8. Laci says:

    How can I use GWT 2 with JBoss 6?

    This solution works on Jboss 4.2.3 for me. But on Jboss 6 it isn’t.

  9. Nuno says:

    hi,
    i’m using seam 2.2.0, gwt 2.2 and jboss 5.1, i’ve followed your instructions but when i call seam/resource/gwt2, i get 404 error 😦
    any ideas to solve this? thanks

    • virgo47 says:

      I haven’t tried GWT 2.2 yet, but I guess the protocol shouldn’t be too different. 404 is hardly our problem. Try to follow some other GWT/Seam integration guide and get to the exception first, then you can go on with step 2 – use our fix. I can’t tell you anything more, 404 indicates that the problem is probably somewhere completely else.

      • Nuno says:

        thanks for your quick answer!

        i’ve already done the GWT/Seam integration, and i get the exception…
        i’m using eclipse, i’ve used seam-gen to generate my project, than in web project i’ve enabled gwt and copied gwt-servlet.jar to WEB-INF/lib, than i’ve got the exception. than i’ve copied your seamgwt2 package to the src folder of the web project, rebuild restart everything, and still got error 404. 😦

      • virgo47 says:

        Nuno, that’s strange. Is that 404 on GWT-RPC request? Use Firebug or something like that to find out which request fails. That said I can’t support you more anytime soon. Maybe later I’ll try to reiterate this with newest Seam 2.2.1, GWT 2.2 and JBoss 6 and 7 too, but one needs a bit of peace to get to it – and I don’t have that right now. 🙂

  10. Flori says:

    Hi Virgo,

    is there a way to bundle your fix as a jar instead of copying the files into the source folder?

    cheers Flori

    • virgo47 says:

      Well… you can Jar them! 😉 No seriously – my friend came up with the fix for our project, but we’re not willing to “distribute” it in any official way. Then someone comes and asks for Maven repo, etc. I really don’t need that for a bunch of classes – and hopefully just temporary (a few years) solution anyway. So you’re stuck with the oldest reusability method out there – copy and paste. 😉

      • Flori says:

        Yes I can! 😉 Well I bundled the sources as jar, added the jar to the Java build path + deployed-jars-ear.list and started a redeploy of my application (seam 2.1.2) but the only thing which happens is:
        HTTP Status 404 – The requested resource () is not available.

        No idea why it does not work as expected .. But that would only be nice to have. Without jar it does perfectly!

      • Flori says:

        Hooray, it works! I still had to do 2 things:

        Added META-INF/seam.properties
        Annotated GWT2Service & GWTToSeamAdapter with @Startup

        I think this is very much nicer to install than source files to copy, so if u want I can send you the jar (copy into lib & add to deployed-ear.list – use seam/resource/gwt2 as endpoint – that’s all).

        @Virgo
        Also I’m working out to connect GWTP Dispatch with Seam. However GWTP is under the Apache License, Version 2.0. Is this compatible with the LGPL license, or would this be a problem? I hope not 🙂 .

      • virgo47 says:

        Flori, you have to realize that “our” code is just copied from Seam (and their code is mostly copied from GWT RPC classes) and their licences apply. So you somehow have to “rewrite” the code. But as Seam integrators probably took most of the parts from GWT client side and added some annotations for resource handler, you should be OK – GWT is also Apache License after all.

        For best results (we just published our “hack” to help you guys – and it worked!) I’d go through GWT client classes, check what is from that code, added resource handler annotations for Seam (modify or enahnce a few lines to claim the code :-)) and you’re done. I’d definitely review the code before making it any serious.

      • Flori says:

        Yes, I realized that and I’m not going to make it serious really ;)…. I’m just going to provide a quick fix for everyone who want to use GWTP Dispatch with Seam – and as you had already written before hopefully just as temporary (a few years) solution anyway 😉

    • virgo47 says:

      BTW – anyone tried Seam 2.2.1? No progress?

      • Nuno says:

        it works!!! jboss 5.1, seam 2.2.1 and gwt 2.2, i’ve copied gwt-servlet.jar(from gwt not the one that comes with seam) to EAR project instead of WAR and i’ve copied seamgwt2 package to EJB project instead of WAR project.

        thanks virgo47 for your help, and nice peace of code 🙂

      • virgo47 says:

        I’m glad you sorted it out. 🙂

  11. Nuno says:

    i sandy,
    i’m using eclipse 3.5.2 with jboss seam tools and gwt plugins and these are the steps i’ve followed to integrate jboss 5.1, seam 2.2.1 and gwt 2.2:
    – create seam web project
    – seam generate entities (to build jpa artifacts to work with by db)
    – copy gwt-servlet.jar to EAR project, lib folder. (this jar is from gwt and not from seam)
    – copy jboss-seam-remoting.jar to EAR project, lib folder. (this jar is from seam)
    – in the web project properties check this 2 jars in java ee module dependecies
    – in the web project i’ve enable gwt web toolkit settings.
    – i’ve copied seamgwt2 package(you can download it on this page) to EJB project.

    and… thats all!!

    note:
    i’ve some problems with serialization and jpa objects, i’ve solved this using gilead (http://noon.gilead.free.fr/gilead/)

    hope it helps

    • virgo47 says:

      Thanks Nuno for your miniguide. The points here generally are:
      – you have to have seam-remoting (from Seam) and GWT servlet (from GWT, Seam has old version!) on classpath and so must be our seamgwt2 classes
      – when Seam goes through the project he finds our classes and adds new resource handler (gwt2)
      – some ppl had problem to use one seamgwt2 for more wars or exactly the oposite – can’t remember now (if you have one WAR, you should be ok)

      I plan to put together “Hello World” for this, but right now I have so many other plans that I can’t promis that.

    • Sandy Noa says:

      Finally, I could make it works, but I’m having the same problem with serialization,
      Would you like to show the steps you follow when using gilead ???

  12. Sandy Noa says:

    I’m still in troubles, now I modify the steps I had followed above by the ideas of Flori:

    1- Added an empty META-INF/seam.properties file to my Seam Web Project
    2- Annotated GWT2Service & GWTToSeamAdapter with @Startup
    3- Make a jar called seamgwt2.jar with updated classes
    4- Remove the seamgwt2 old folder from my EJB project
    5- Copy the new jar into my lib folder of Seam Web Project (even I added it to build path and nothing)
    6- Copy the new jar to EarContent/lib of my EAR project
    7- I use seam/resource/gwt2 as endpoint:

    private MyServiceAsync getService() 
       {       
          String endpointURL = GWT.getHostPageBaseURL() + "seam/resource/gwt2";            
          MyServiceAsync svc = (MyServiceAsync) GWT.create(MyService.class);
          ((ServiceDefTarget) svc).setServiceEntryPoint(endpointURL);
          return svc;     
       } 
    

    8- The content related to the servlet at file WebContent/WEB-INF/web.xml of my Seam Web Project is:

    Seam Resource Servlet
    org.jboss.seam.servlet.SeamResourceServlet

    Seam Resource Servlet
    /seam/resource/*

    9- The src’s structure of my Seam Web Project is:

    – client
    – server
    – public
    – HelloWorld.gwt.xml

    10- The content of HelloWorld.gwt.xml is:

    Finally if I try to run JBossAS 5.1 I get an error, I only could run the project as “Web Application” in hosted mode, but when I clic the Ask button I receive this message: 404 Cannot find resource ‘seam/resource/gwt2’ in the public path of module ‘cu.uci.HelloWorld’.
    Maybe I’m missing something, but I can’t find what is. Also I was trying to adapt the remoting example of Seam 2.2.0 GA framework. How could I run a simple example in Eclipse ???

    some help will be OK…
    thanks a lot (Virgo, Flori, Nuno, …).

    • Flori says:

      Hi Sandy,

      you have to add the META-INF/seam.properties to your exported seamgwt2.jar not to your Seam Web Project (by default there should already be one)!

      “Seam components are installed when the deployment scanner discovers a class with a @Name annotation sitting in an archive with a (META-INF/) seam.properties file or a META-INF/components.xml file.”

      Hope it works, the rest of your setup seems to be ok!
      cheers

  13. Sandy Noa says:

    Thanks Fiori but nothing of nothing.
    I would like so much that you or maybe some other people could publish here the complete content (sources) of src folder of any simple Seam Web Project, really many persons like me are trying to run 1 simple and functional example with GWT & Seam 2, because Seam 3 is really complex and the support of Errai module is madden by only 2 developers of Red Hat (Heiko Braun and Mike B.)
    I hope virgo appreciate it.
    One good thing: this blog is very ACTIVE, thanks for it.

  14. Nuno says:

    i’ve a simple project working with seam 2.2.1 and gwt 2.2, this was built on eclipse 3.5 and runs on a jboss 5.1.
    you can checkout it from google:
    svn checkout http://peste-control.googlecode.com/svn/trunk/ peste-control-read-only

    • Sandy Noa says:

      Nuno, I have a question for you, what are the dependences between the GWT project and the others (in terms of build path, project references, …) ???

      thanks…

    • Sandy Noa says:

      I get this error when I compile my GWT project:
      Compiling module cu.uci.GWTProject
      Validating newly compiled units
      [ERROR] Errors in ‘file:/media/…/GWTProject/src/cu/uci/client/GWTProject.java’
      [ERROR] Line 30: No source code is available for type cu.uci.seampostgres.client.services.GreetingServiceAsync; did you forget to inherit a required module?
      [ERROR] Line 36: No source code is available for type cu.uci.seampostgres.client.services.GreetingService; did you forget to inherit a required module?
      Removing invalidated units
      Finding entry point classes
      [ERROR] Unable to find type ‘cu.uci.client.GWTProject’
      [ERROR] Hint: Previous compiler errors may have made this type unavailable
      [ERROR] Hint: Check the inheritance chain from your module; it may not be inheriting a required module or a module may not be adding its source path entries properly

    • Sandy Noa says:

      With that model, do you have access to Seam contexts like conversations, session, application, … ? How is it possible ?

    • Sandy Noa says:

      Nuno, could you please answer my question, I’m still in troubles.
      Thanks, …

  15. Sandy Noa says:

    I have a Spanish blog with my issues right here:
    http://gwtseam.blogspot.com/

  16. Thanks a lot. It’s working perfectly in SEAM 2.2 and JBOSS 4.2.3, but everytime I modify a class in the server side and the component is hot deployed I get an error in the GWTToSeamAdapter. Did you get the same error during development?

    To solve it, I had to make some changes in the GWTToSeamAdapter. Basically I turned it in a simple singleton class (no SEAM support) and removed the method chace in getMethod method.

    My question is – Removing this method cache mechanism will generate any problem in my app?

    • virgo47 says:

      Sorry, I can’t tell… just to let you know. 🙂 I’m not working with this stack for some time now.

    • Flori says:

      Can you provide a patch? Maybe I can then answer your question. Since I’m using this fix I am interested in any improvement 🙂

      • Sure Flori. I’ll try to post the changes here, but if you prefer I can e-mail it to you later.

        Class declaration:

        public class GWTToSeamAdapter {
        
           private static GWTToSeamAdapter instance;
           
           /** A very simple cache of previously looked up methods */
           private final Map METHOD_CACHE = new HashMap();
           
           private GWTToSeamAdapter() {
        	   instance = this;
           }
           
           public static GWTToSeamAdapter instance() {
              //GWTToSeamAdapter adapter = (GWTToSeamAdapter) Component.getInstance(GWTToSeamAdapter.class);
        	   if (instance == null)
        		   instance = new GWTToSeamAdapter();
        	   GWTToSeamAdapter adapter = instance;
        
             if (adapter == null) {
               throw new IllegalStateException("No GWTToSeamAdapter exists");
             }
        
             return adapter;
           }   
        

        and in the method getMethod method

           private Method getMethod(String serviceName, String methodName, Class clz, Class[] paramTypes) {
              String key = getKey(serviceName, methodName, paramTypes);
                 try {
                    synchronized (METHOD_CACHE) {
                       Method m = findMethod(clz, methodName, paramTypes);
                       if (m == null)
                          throw new NoSuchMethodException();
                       METHOD_CACHE.put(key, m);
                       return m;
                    }
                 } catch (NoSuchMethodException e) {
                    throw new SecurityException("Unable to access a service method called ["
                                + methodName
                                + "] on class ["
                                + clz.getName()
                                + "] without the @WebRemote attribute. "
                                + "This may be a hack attempt, or someone simply neglected to use the @WebRemote attribute to indicate a method as"
                                + " remotely accessible.");
                 }
              }
        

        If you want I can send the whole file by e-mail, but basically these are the changes I did.

        As I said before, the only problem I found in your implementation is during hot deployment in a development enviroment, where classes seem to be in a different class loader and I have to restart the whole application, but under production I didn’t get any issue.

        Thanks,
        Ricardo

    • Sandy Noa says:

      Ricardo, for some months I was trying an integration between Seam 2.2 and GWT, but I couln’d do it. Could you please HELP ME and publish in some site the complete projects (GWT project, EJB, …) in a zip file and the steps you follow to get this integration.

      Thanks a lot…
      You are my last attempt.

  17. Khurram says:

    Awesome write up! A question though, I am able to get it working now thanks to your patch with GWT 2.1.1 and Seam 2.2.1Final, however, when my application is finished authenticating, it gives me javascript errors which were not there prior to upgrading from GWT 1.7.1. Error is inline about not finding a function. It works fine in the Hosted mode but when I deploy it to JBoss it gives this error making me think it’s something to do with the JBoss settings of some sort, etc…

    any idea?

    Thanks.

  18. Sandy Noa says:

    Could somebody publish the integration’s steps from scratch between GWT 2.x and Seam 2.x ???
    Thanks.

  19. christian nzhie says:

    Hi, i have may be the same problem.
    i’m using gwt2.0.4 with myeclipse

    i hava some error occur when i deploy my application on a tomcat server.
    in developpement mode it work well but when i compile and deploi it in to server tomcat i have the folowing error :

    Grave: greetServlet: An IncompatibleRemoteServiceException was thrown while processing this call.
    com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: java.lang.NumberFormatException: For input string: “undefined”
    at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:308)
    at org.gwtrpcspring.RemoteServiceDispatcher.processCall(RemoteServiceDispatcher.java:32)
    at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:224)
    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.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:429)
    at org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:384)
    at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1665)
    at java.lang.Thread.run(Unknown Source)
    Caused by: com.google.gwt.user.client.rpc.SerializationException: java.lang.NumberFormatException: For input string: “undefined”
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserialize(ServerSerializationStreamReader.java:569)
    at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:61)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader$ValueReader$8.readValue(ServerSerializationStreamReader.java:137)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserializeValue(ServerSerializationStreamReader.java:384)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserializeClass(ServerSerializationStreamReader.java:658)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserializeImpl(ServerSerializationStreamReader.java:704)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserialize(ServerSerializationStreamReader.java:548)
    at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:61)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader$ValueReader$8.readValue(ServerSerializationStreamReader.java:137)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserializeValue(ServerSerializationStreamReader.java:384)
    at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:296)
    … 17 more
    Caused by: java.lang.NumberFormatException: For input string: “undefined”
    at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
    at java.lang.Double.parseDouble(Unknown Source)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.readDouble(ServerSerializationStreamReader.java:475)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.readLong(ServerSerializationStreamReader.java:495)
    at com.google.gwt.user.client.rpc.core.java.lang.Long_CustomFieldSerializer.instantiate(Long_CustomFieldSerializer.java:35)
    at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.instantiate(ServerSerializationStreamReader.java:870)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserialize(ServerSerializationStreamReader.java:544)
    … 27 more

    please some can help me……….
    it’s to important for me thank’s , regards

  20. christian nzhie says:

    Hi is me to,
    Could you tel me how i can compile fasly my projet.it’s made more time. 1h some time.
    how i can optimise my process, or is it possible to compile some class and deploy them in to the jar?

  21. virgo47 says:

    I’m sorry, but I have no spare time to support this post beyond what was said in it or in the comments.

    • christian nzhie says:

      Hi guy, i’m sory but no problem.
      just want to have and idie on how to solve the first probleme. because in deveoppement mod it work well, but when i deploy in tomcat server, i have that fololowing error

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s