Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullPointerException when invoking Remoting Service #5

Closed
espinaca opened this issue Mar 26, 2014 · 6 comments
Closed

NullPointerException when invoking Remoting Service #5

espinaca opened this issue Mar 26, 2014 · 6 comments

Comments

@espinaca
Copy link

Dear emilkm,

My question is very simple, but I need to explain a little of my web application, I hope to be clear and not confuse.

I have a web application using Java, BlazeDS, Spring and the front-end it is made with FLEX... works great.

Now I want to change the front-end and using HTML5/Javascript, I plan to use the services exposed with BlazeDS so I need a library like yours.

I've done some testing and I can connect fine to "endpoint", for example, with flex I sent the authentication through method "ChannelSet.login(user, password)" which is nothing more than sending a simple "flex.messaging.messages.CommandMessage" with an "operation" equal to 8 and in the "body" the credentials encoded in base64, I've done this with his library and works very well.
This can be seen in the source code of the method ChannelSet login. http://opensource.adobe.com/svn/opensource/flex/sdk/branches/3.4.0/frameworks/projects/rpc/src/mx/messaging/ChannelSet.as

So far all was well!

But, what I do not know is whether through your library can consume "RemotingDestination" (a simple service exposed with BlazeDS) because whenever I try to get to the service, the server sends me an error like this:

[btpool0-1] 2014-03-26 13:29:44,232 DEBUG SessionListener - Flex session created with id '17mj7k4e2xrou'
[btpool0-1] 2014-03-26 13:29:44,420 INFO AuthenticationServiceImpl - Authentication success with username : espinaca@espinaca-domain.com
[BlazeDS]Exception when invoking service 'remoting-service': flex.messaging.MessageException: java.lang.NullPointerException
incomingMessage: Flex Message (flex.messaging.messages.RemotingMessage)
operation = getUser
clientId = 74AE87D6-C10D-8E1D-170C-3625EE23F6A6
destination = userService
messageId = dba12e2a-74cf-4e31-aa22-180fe823ca3e
timestamp = 1395862186209
timeToLive = 0
body = null
hdr(DSEndpoint) = inca-amf
Exception: flex.messaging.MessageException: java.lang.NullPointerException
at flex.messaging.services.RemotingService.serviceMessage(RemotingService.java:225)
at flex.messaging.MessageBroker.routeMessageToService(MessageBroker.java:1503)
at flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:884)
at flex.messaging.endpoints.AbstractEndpoint$$FastClassByCGLIB$$1a3ef066.invoke()
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.flex.core.MessageInterceptionAdvice.invoke(MessageInterceptionAdvice.java:66)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
.
.
.

With your library may call a "RemotingService" BlazeDS? and if is so, you know that is causing this "java.lang.NullPointerException", What's not clear is whether the problem is in your library or in my server settings BlazeDS :(

I hope you can guide me a bit

Best regards!

@emilkm
Copy link
Owner

emilkm commented Mar 27, 2014

espinaca,

You can use this library but with some limitations. As it was designed mainly with mobile development in mind, a great deal of effort was spent in removing all "unnecessary" functionality. You may also notice that only the bare minimum fields in all remoting objects are sent/received. This was done with the intention to reduce the amount of data transferred while still being able to use the AMF protocol.

I know that Adobe have an AMF Client library specifically designed for HTML5/Javascript with full support for ChannelsSets, Channels, etc. If you are after the smoothest ride your best bet is try that library.

Using amfjs would require some additional work on the server as well as the client. I have primarily worked against a modified AMFPHP server. Also tested against a bare minimum BlazeDS server, but only to verify packets are encoded and decoded correctly.

davidef forked this library at https://github.com/davidef/amfjs, and, I think, is using it with BlazeDS sever. He may be able to help you better with BlazeDS.

Kind Regards
Emil

@espinaca
Copy link
Author

Mr Emil, thank you very much for your quick response, I comment that it had previously reviewed the API Adobe specifically "Lc DS" which contains a javascript AMF client, but I never work for me :(

Your library works fine, the problem is that in the "body" of the message was sending a NULL that caused this exception.

Have a great day.

espinaca.

@emilkm
Copy link
Owner

emilkm commented Mar 27, 2014

Great to hear you have figured out the problem and that the library works for you.

I had left the body of the CommandMessage with its default value of empty array commented out as an indication.

Good luck with rewriting your application in HTML5. I hope it isn't a big business app :)

I would be interested to know what other JavaScript frameworks you are using.

Cheers
Emil

@emilkm emilkm closed this as completed Apr 6, 2014
@Sjafari
Copy link

Sjafari commented Sep 21, 2015

Hi @espinaca and @emilkm,

I am also struggling to create an amf client which communicates with a BlazeDS server.
I would love to use your library but is there any examples or tutorials that I can refer to?
Atleast the basics like sending request/recieving response of a simple comand & remoting message. Creating custom remoting message etc.

Any help will be much appreciated.
Thanks

@collinforrester
Copy link

@emilkm Could you put some example code in here on how you were able to replicate the ChannelSet.login functionality? The source link you provided now requires authentication.

I'm able to make regular AMF calls if they're not secured. But all other calls require me to auth with ChannelSet first.

@emilkm
Copy link
Owner

emilkm commented Jul 15, 2016

Hi,

The source link was provided by @espinaca

Howerver, BlazeDS is open source and it was contributed to Apache. A Mirror of Apache Flex BlazeDS can be found here https://github.com/apache/flex-blazeds

An example that works with https://github.com/emilkm/efxphp can be found here https://github.com/emilkm/efxphp-bootplate/blob/master/public/amfjssaucer.html

holdQueue can be used to hold the queue while you setup a session for example.

var endpoint = window.location.href.substr(0, window.location.href.lastIndexOf('/')) + "/server/index.php";
var amfClient = new amf.Client("efxphp", endpoint);
amfClient.invoke("myapp.server.MyService", "init", [],
    function(response, token) {
        console.log(response.data);
        amfClient.setSessionId(response.data);
        amfClient.releaseQueue();
    },
    function(error, token) {
        console.log("init error");
    },
    "init",
    true
);

amfClient.invoke("myapp.server.MyService", "publicMethodNoParams", [],
        function (response, token) {
            console.log(response.data);
        },
        function (response) {
            console.log("publicMethodNoParams error");
        }
);
amfClient.invoke("myapp.server.MyService", "publicMethodOptionalParam", [],
        function (response, token) {
            console.log(response.data);
        },
        function (error, token) {
            console.log("publicMethodOptionalParam error");
        }
);
amfClient.invoke("myapp.server.MyService", "publicMethodMandatoryParam", [1],
        function (response) {
            console.log(response.data);
        },
        function (error, token) {
            console.log("publicMethodMandatoryParam error");
        }
);

Lets say the server will return an error for all requests that do not have a valid session. You want to avoid making such requests.
You can first invoke an init method, setups a session, telling the library to hold the queue until you release it. Then without having to structure your code in such as to wait for the session to be setup, you continue with further requests. These would be held in the queue until you release the queue by executing releaseQueue();

You can pass any credentials to the init method.

The only supported command message is CLIENT_PING_OPERATION. That is sent automatically by the library before the first request.

I do not work with BlazeDS, but think it may be possibly to establish a session manually. I think that the way ChannelSet.login works is that it will create a session and pass it back to client telling it to appendToGatewayUrl. Subsequent requests then have the sessionId as part of the URL.

Assuming I am correct, you can achieve the same result with the above example.

amfClient.setSessionId('sessionidvalue');

Sets the session id. Here is what the method looks like

amf.Client.prototype.setSessionId = function(value, releaseQueue) {
    this.sessionId = value;

    if (this.sidPropagation == "header") {
        this.addHeader('sID', this.sessionId);
    } else {
        this.endpoint += '?sID=' + this.sessionId;
    }

    if (releaseQueue === true) {
        this.releaseQueue();
    }
};

One may need to change the session variable name to 'jsessionid', or whatever BlazeDS expects

The session is propagated in one of the two currently supported ways

  • AMF header
  • Query String

I have never had the need to customize the RemotingMessage before. It really depends on what the server is expecting. Sure, I have removed properties from the Command Message

CommandMessage: function() {
        return {
            _explicitType: "flex.messaging.messages.CommandMessage",
            destination: "",
            operation: 5,
            //body: [],
            //headers: {DSId:"nil"},
            clientId: null
        };
    },

knowing that my server never uses those, and does not break if they are not present.

If BlazeDS or any other server insists on having those, then they should be part of the message.

If you do want to customize the RemotingMessage, you could simply change the library a bit, by adding, removing, or modifying properties in the RemotingMessage

RemotingMessage: function() {
        return {
            _explicitType: "flex.messaging.messages.RemotingMessage",
            destination: "",
            source: "",
            operation: "",
            body: [],
            headers: {DSId: "nil"},
            clientId: null
        };
    },

Hope this helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants