How to connect XMPP bosh server using java smack library? - java

I have working xmpp client on webapp using strophe.js ,as per my use case scenario i have to switch to different pages rapidly
Current approach is not secure as jid and password is visible in java script ,I was finding work around to implement security in strophe client an trying to make connection time(with bosh) more shorter ,while going through the book "XMPP Programming with JavaScript and jQuery"by jake moffitt i came across one solution which element both of my above problems is to implement session mechanism.which says that we can use strophe attach(jid,sid,rid) to connect to existing connection,so i need SID and RID ,which i can get from application server!!!
book has given an example of automated connection to bosh server when user logged in the web application,author has implement it using an Django project in python,As I am using java as server side language i tried to implement same example using java smcak-4.0.3 and smack-bosh-4.0.3
but unable to connect to bosh server(i am using ejabberd as xmpp server)
my code is as below
BOSHConfiguration config = new BOSHConfiguration(false,"192.168.0.106",5280,"/http-bind/","192.168.0.106");
XMPPBOSHConnection xbc=new XMPPBOSHConnection(config);
xbc.connect();
xbc.login("admin", "admin");
System.out.println(xbc.getConnectionID());
stack trace
java.lang.ClassNotFoundException: org.xmlpull.v1.XmlPullParserFactory
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
at org.jivesoftware.smack.SmackConfiguration.processConfigFile(SmackConfiguration.java:352)
at org.jivesoftware.smack.SmackConfiguration.processConfigFile(SmackConfiguration.java:347)
at org.jivesoftware.smack.SmackConfiguration.<clinit>(SmackConfiguration.java:155)
at org.jivesoftware.smack.ConnectionConfiguration.<init>(ConnectionConfiguration.java:67)
When i tried to login to bosh server it fails every time,i am not sure what is wrong here can some one explain me?
One more thing i have find is one can get session identifier(SID) using "xbc.getConnectionID()" but how to find request identifier?
Any help on above problem will be appriciable!!!!
thanks in advance!

I had a similar problem.
I donwload all the smack github I import smack.jar from /lib/ and add the 3 java files from /src/main/java/org/jivesoftware/smack/
I tried to fix it by importing smack-bosh-3.2.2-jar-with-dependencies.jar from /target/. I don't know why this diddn't work.
Finally, I read here that you need to download all the dependencies libraries :
jbosh-0.6.0.jar
xlightweb-2.5.jar
xSocket-2.4.6.jar
xpp3-1.1.3.3.jar
dom4j-1.6.1.jar
So I used smack.jar from /lib/ with all thoses libraries and this problem was solved.
As i said in comments, you need after to retreive RID. I used jbosh sources and add following lines :
In com.kenai.jbosh.BOSHClient class
//I introduced a new property
private Long rid;
//commented the following code
//long rid = requestIDSeq.getNextRID();
//and at that place added
this.rid = requestIDSeq.getNextRID();
//and finally added a new getter for rid
public Long getRid() {
return rid;}
Then in smack-bosh :
In BOSHConnection.java
public Long getRid() {
return client.getRid();}
public String getSid() {
return sessionID;}
Now I'm blocked cause my session is disconected. According to my openFire logs, it's because of overactivity. So I'm looking for a solution to reduce the number of presence messages.

To get latest benefits in Android BOSH you need Smack Releases 4.1.1
SMACK --- smack-tcp smack-sasl-provided smack-resolver-minidns smack-resolver-dnsjava smack-extensions smack-core smack-bosh smack-android-extensions smack-android
You additionally Need
XPP3 1.1.4c delete the javax package from the JAR file for android because android already have javax....QName class
JXMMP, JXMMP CACHE, JBOSH, MINIDNS, DNSJAVA, JSTUN, XBILL DNS
No need for Apache HTTP Client which is already available in android
Unfortunately it comes around some 12 JAR files,
better use Maven Android Project in Eclipse
Otherwise search the above keywords at Maven Central http://search.maven.org/#search and get the JAR files one by one

stack trace
java.lang.ClassNotFoundException: org.xmlpull.v1.XmlPullParserFactory
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
at org.jivesoftware.smack.SmackConfiguration.processConfigFile(SmackConfiguration.java:352)
at org.jivesoftware.smack.SmackConfiguration.processConfigFile(SmackConfiguration.java:347)
at org.jivesoftware.smack.SmackConfiguration.<clinit>(SmackConfiguration.java:155)
at org.jivesoftware.smack.ConnectionConfiguration.<init>(ConnectionConfiguration.java:67)
The exception here clearly states that Webapp cant find class org.xmlpull.v1.XmlPullParserFactory. That sounds like you are missing xml-apis library in your classpath, (or some other implementation of XmlPullParser interface).

Related

error to integrate restful web service with spring and gdata api

Short version: A restful spring web service crashes when I include a dependency: com.google.gdata: core: 1.47.1
Long Version:
I was trying to make a restfull web service that consume certain information from a spreadsheet in google drive
this is my sequence of steps:
preparing classes that made the connection and the data obtained from drive (not web, only backend classes, unit and integration tests included): all ok
prepare a restfull web service with spring, basically download a spring tutorial (http://spring.io/guides/tutorials/rest/3/) and execute: all ok
then remove tutorial's business classes and include my components, change controllers to invoke my components, plus add gdata dependence in file graddle.build, try execute: houston we have a problem
It's strange, when start app context, log print something like this:
 
C:\Users\Grubhart\Documents\proyectos\error_Rest_Gdata\complete\src\main\java\com\yummynoodlebar\config\WebAppInitializer.java:39: error: can not find symbol
     servletContext.setInitParameter ("defaultHtmlEscape", "true");
                   ^
     symbol: method setInitParameter (String, String)
     location: Variable of type ServletContext ServletContext
but when the rest app is just downloaded (whitout my code, neither gdata dependency) it works, the only thing I did was add my code and the google api dependence, so I started to see what could cause the error
remove all my code (but leave the gdata jar) and... wait for it.. same error,
remove gdata dependency: it works
then add gdata dependency again and test: the same error again
So I think that by including the gdata jar does something that prevents start the entire app context
I created a repo on github to illustrate the error:
https://github.com/Grubhart/error_spring_restWS_gdata
the master branch has the code of a service that works without gdata dependence
gdata_error branch as you can imagine has added gdata dependency (only dependency, no extra code) in gradle.build file:
compile 'com.google.gdata: core: 1.47.1'
and presents the error
no need install anything (even gradle) only have jdk, download the code and run it as stated in the readme file to see errors
i do my homework, look in google, stackoverflow (great site!), spring forum but can't find nothing
if anyone has experience with this problem, or know where i can found more information would be great if you can share experiences or if you know where to look for more info about this error
The original post doesn't contains:
yummynoodlebar\config\WebAppInitializer.java:39: error: cannot find symbol
servletContext.setInitParameter("defaultHtmlEscape", "true");
ServletContext needs import javax.servlet.*; Maybe the error is for that.
Since the spring context configuration in java classes for web applications works with Servlet 3.0 maybe you have overwritten troubles between some dependencies that comes with gdata which may do use of dependencies other than the servlet version you are using to deploy the application or which it was originally configured, I hope this helps you!.

calling wsdl based webservice from within alfresco

i followed this article: http://www.mkyong.com/webservices/jax-ws/jax-ws-hello-world-example/
so i have:
HelloWorld http://pastebin.com/BJ3QA7pR
HelloWorldImpl http://pastebin.com/RM5SBZ5C
HelloWorldPublisher http://pastebin.com/H525WevK
which serves as the endpoint.
on the other side i have the client which i generated with wsimport:
HelloWorld http://pastebin.com/g07H1exf
HelloWorldImplService http://pastebin.com/f0YWMiYt
this runs fine in eclispe without alfresco being involved. however, i want to call the webservice from alfresco (from java backed web script for example)
i tried to copy the client side stuff to my amp file and calling it from a webscript but it fails!
Caused by: java.lang.IncompatibleClassChangeError: Class com.ibm.wsdl.DefinitionImpl does not implement the requested interface javax.wsdl.extensions.AttributeExtensible
Webscript http://pastebin.com/7JksRdtU
1 - is there a more elegant way to configure the access to the wsdl by defining a spring bean (spring-ws) or such
2 - why is it not working? full trace: http://pastebin.com/ak1qzygA
using alfresco community 5.0.a
thanks
You will see IncompatibleClassChangeError usually when the dependancy/library jar has changed. Hence the method/code dependant on the library has to be recompiled against the changes.
Guessing the problem here has much to do with some dependancy jar being mispicked or an older version of jar present or one jar prioritized over the other. A look into the jars containing 'com.ibm.wsdl.DefinitionImpl' class in your classpath should be of some help.

Invoke a GWT RPC Service from Java, problems with RPC policy

I need to invoke a GWT RPC service from simple Java code. Yes, I read this
Invoke a GWT RPC service from Java directly
However, my issue is that I do not have access to the web application code (though I could ask and obtain some parts of it), so I cannot just add it to the build path of my Java project. All the info I read from the internet is not clear on what exactly needs to be imported.
The question is: what is the minumum that I should include in my project in order to make the call to the service work (using syncproxy gwt for example)? Will it be enough to redefine the client interfaces inside my code or should I do some compiling work as well?
EDIT: I've done some testing locally with the default web app running on localhost. I created a new java project, imported the sync and async service interfaces and the RPC serialization policy I found in the WAR folder of the web app. This is my testing code
import com.gdevelop.gwt.syncrpc.SyncProxy;
public class serviceCall {
private static final String MODULE_BASE_URL = "http://127.0.0.1:8888/gwttestapp/";
private static final String SERVICE_NAME = "greet";
public static void main(String[] args) {
GreetingService rpcService = (GreetingService) SyncProxy.newProxyInstance(GreetingService.class, MODULE_BASE_URL, SERVICE_NAME, "CB32CC2E454EE7E1088B2E29CEB44F84");
String result = rpcService.greetServer("SyncProxy");
}
}
However the server seems not to recognize the RPC policy, since I get the following exception:
Exception in thread "main" com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: This application is out of date, please click the refresh button on your browser. ( Blocked attempt to access interface 'GreetingService', which is not implemented by 'com.apptesting.server.GreetingServiceImpl'; this is either misconfiguration or a hack attempt )
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamReader.instantiate(SyncClientSerializationStreamReader.java:746)
at com.gdevelop.gwt.syncrpc.SyncClientSerializationStreamReader.deserialize(SyncClientSerializationStreamReader.java:816)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:119)
at com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.doInvoke(RemoteServiceSyncProxy.java:204)
at com.gdevelop.gwt.syncrpc.RemoteServiceInvocationHandler.invoke(RemoteServiceInvocationHandler.java:193)
at com.sun.proxy.$Proxy0.greetServer(Unknown Source)
at serviceCall.main(serviceCall.java:11)
Anybody can help?
Try initiating the rpcService without the .gwt.rpc policy specified. IE, just make the call:
GreetingService rpcService = (GreetingService) SyncProxy.newProxyInstance(GreetingService.class, MODULE_BASE_URL, SERVICE_NAME);
You generally do not need to specify the exact serialization policy as the RPC system should automatically figure it out. In fact, it's better not to specify it because the deployed site will change the serialization policy file as the back-end changes. Take a look at the source and testing wiki (https://code.google.com/p/gwt-syncproxy/wiki/SourceAndTesting) for some guidance on on setup need needs. The source code for the Android testing app may provide you some code guidance on creating a functional standalone (if you ignore the AsyncCallback implementations)
In general answer to your question, for deployment purposes, all you really are the interfaces you specified (*Service & *ServiceAsync). For testing purposes in your development environment, you can mock some *Impl files that will provide you some generic responses for testing (such as in the default web-app). Take a look at the Android Wiki in the sync-proxy project (https://code.google.com/p/gwt-syncproxy/wiki/Android) at the setup section for a quick overview on linking the needed files.
Disclaimer: I'm a developer for the Android syncproxy library

Google Cloud Endpoints - APIs not updating

I've been playing around with Google Cloud Endpoints (Java) and I'm having trouble getting the APIs to update after I deploy to App Engine (using both Eclipse + Google Plugin and Android Studio).
I created an Endpoint based on a class called Process (annotated with JPA). It sits in my package (let's say: com.example). The first time I deployed it I had accidentally imported the wrong class (java.lang.Process instead of my com.example.Process). So I got this error when I tested one of the methods in the API explorer:
com.google.api.server.spi.SystemService invokeServiceMethod: cause={0}
javax.persistence.PersistenceException: No meta data for java.lang.Process. Perhaps you need to run the enhancer on this class?
I have then corrected the import, re-generated the client libraries and re-deployed the app to App Engine, but I keep getting the same error. As if App Engine still thinks I'm using java.lang.Process instead of my Process class.
I also made other changes. Like class member variable types and method names and re-deployed. But App Engine doesn't seem to notice these changes.
I read about how the API explorer "violently caches" so I tried clearing the cache, opened in another browser and even on another PC. Still nothing.
Also, I opened the discovery files for my api located in https://.appspot.com/_ah/api/discovery/v1/apis//v1/rest
I noticed that the variables types I had changed are still listed as the old types.
I checked the logs for my deploys. They all look ok:
2013-07-06 18:59:59.960 /_ah/spi/BackendService.getApiConfigs 200 291ms 14kb
I 2013-07-06 18:59:59.706 com.google.api.server.spi.BackendService getApiConfigs: apiConfigDir=/base/data/home/apps/s~<my-app>/1.368601601499931812/WEB-INF
I 2013-07-06 18:59:59.707 com.google.api.server.spi.BackendService getApiConfigs: apiConfigFile=/base/data/home/apps/s~<my-app>/1.368601601499931812/WEB-INF/<my-api-name>-v1.api
I 2013-07-06 18:59:59.713 com.google.api.server.spi.BackendService getApiConfigs: apiConfigFile=/base/data/home/apps/s~<my-app>/1.368601601499931812/WEB-INF/messageEndpoint-v1
I 2013-07-06 18:59:59.740 com.google.api.server.spi.BackendService getApiConfigs: apiConfigFile=/base/data/home/apps/s~<my-app>/1.368601601499931812/WEB-INF/deviceinfoendpoint
and in Admin Logs:
2013-07-06 18:59:35 <me> Successfully updated API configuration version=1
2013-07-06 18:59:35 <me> Completed update of a new default version version=1.2013-07-06T21:59:30Z
2013-07-06 18:59:32 <me> Deployed a new version version=1.2013-07-06T21:59:30Z
Anyone has any idea?
Thanks in advance.
It doesn't seem like your .api files are regenerating properly. If you delete the .api files, do they regenerate upon loading either in dev or to the App Engine?
Common reasons why .api files are re-created with updated information (i.e., mistakes I made in the past):
Primitives and enums are not allowed. You must pass back a Bean.
API methods are not annotated
API methods are "private" instead of "public"

Java JMS = HornetQ = javax.jms.JMSSecurityException: Unable to validate user: null?

I am trying for several hours to get the HornetQ Examples running in Eclipse. Using the Standalone Examples everything works fine, but when I run the examples in Eclipse I get the following error:
javax.jms.JMSSecurityException: Unable to validate user: null
What could this error mean? Where do I have to specify the user? Maybe HornetQ tries to look this user up in "Some Context/Properties" etc , but I do not know where and how to specifiy the user HornetQ is running under.
What i did:
1.)Started Default HornetQ Server with the start.sh Script in the ./bin directory
2.)Copied the QueueExample over to eclpise
3.)Did some minor changes in the config files (to have the same Queue Names...)
(I also tried to disable security completely by setting:
<security-enabled>false</security-enabled>
but with no success, always getting the same error. Also when trying to programmatically instance HornetQ only via classes I get this error too).
Thank you very much!!
Jens
Did you have a look at this thread? It seems you need to the permission 'createTempQueue' to the example role.

Categories

Resources