Messaging between Java and Flex with Flerry - java

I'm currently working on a project that need to communicate with java from air without the use of a server like Tomcat. For this i found and use Flerry.
Communicating between Java and Air is no problem, as long as I try to send a message from the class that I initially instantiated from Air.
What I try to do is subscript to messages from a Message Class in java and use that class to send info and errors to Air from Java.
MessageController.java:
public class MessageController
{
public MessageController()
{
}
public static void sendErrorMessage(String errorMessage)
{
NativeObject.sendMessage(errorMessage, "error");
}
public static void sendInfoMessage(String infoMessage)
{
NativeObject.sendMessage(infoMessage, "info");
}
}
In Air I create a NativeObject on the messaging class and subscribe to the messages:
var messageController:NativeObject = new NativeObject();
messageController.source = "controller.MessageController" ;
messageController.singleton = true;
messageController.debug = false;
messageController.addEventListener(FaultEvent.FAULT, onFileControllerFault, false, 0, true);
messageController.subscribe("info", infoMessageHandler);
messageController.subscribe("error", errorMessageHandler);
As you would have guessed, this doesn't work.
It seems that I am only able to dispatch messages from the class that I subscribe to directly, for example if I do this:
messageController.start();
and in my MessageController.java i put this:
public void start()
{
NativeObject.sendMessage("test message", "info");
}
the infoMessageHandler receives an message containing test message, as it should.
How can I dispatch messages from whatever class in Java and catch them on the Air side?

I'm not sure I fully understand the issue yet, but is there a reason you can't simply send and receive all messages through a Java 'communication' class? If that's working, I'd just set up public methods in Java interfacing/communications class and be done with it.
(It's been awhile since I've dug into how Flerry works so I can't recall enough to point out the likely cause of the behavior you're seeing.) Also Flerry is open source, and not very big at all. If you really want to know why it's behaving in a certain way, I'd wager you could figure it out by looking at the source. (Won't take 6 months to learn like some Spring or Hibernate code base, or even BlazeDS, I promise.)
I do use Flerry in a small app, but now that I think about it, I only have one class which dispatches anything to Flex! But I feel like you may need to describe the problem you're facing differently, because it sounds like expected behavior to me.

Related

How can I get programatically any single Log generated by my App?

Any Android App produces Logs in the LogCat, even those not generated by developer's source code via Log.d, Log.i, Log.w and Log.e etc. etc. etc.. Perhaps Google Developers has some "automagic" thing for this, I don't know about that...
The point is I remember, years ago, I could somehow extend the class Application, override one or several of it's methods, and then:
Add my own code to process any single Log object generated by my
App in the LogCat
Do whatever I wanted with them (getting the label and the description strings, and then send them via mail, Slack etc., basically)
And then, calling super on that method and let the system do with that Log whatever Application by default does with it...
or something like that... if I recall correctly, I could do this with any log in my app's namespace. Or maybe it was just the crash handler? I can't remember...
It's been so long since I accomplished that (several years already!), so I don't remember how could I do that anymore... I search the internet like crazy trying to recall, but I am struggling to find it again... :-S
// ...public?? oO
[¿¿??] class MyApp extends Application [...] {
// [...]
#Override
public void whateverMethodItWasIDontRemember(params) {
// My coding stuff for the error reports
/* magic :D */
sendTheLogsMyWay();
// I bet this is important
super.whateverMethodItWasIDontRemember(params);
}
// [...]
}
I am about to launch the first Beta version of a new app, so I want beta testers to have a reliable way to send me LogCat's feed if anything has to be reported due to crashes, unexpected behaviour etc.
I mean, it would be ridiculous having to fill with CustomLogs every inch of source code for the beta version, when, in most cases, default logs are more than enough to see why it crashed (errors), or what optimization problems (usually warnings) might the Beta Tester have... not to mention that, if I forget to monitor something this way, the ridiculously big effort to log every single line of my code would be useless... oO
// -__- Mmm... perhaps extending Log itself
// would be more elegant...
import android.util.Log
public final class CustomLog {
public static void d(String label, String msg) {
// AKA My code to handle it
packItForNextErrorReport(label, msg);
Log.d(label, msg);
}
/*
* ... and so on with Log.i, w and e.
* ...I think you get the idea
*/
}

Use code generation for executing generic tests

I think I have an interesting question and PERHAPS there is already the answer which is still a secret for me, so I hope to get some helps from expers. :)
So here is the thing:
I work for the test/validation team to test our Java API and basically my job is to follow test plan and write the test code. After writing that for more than two months, I find the codes are really similar. For example:
To test function could return expected result or throw exception correctly, we may need write several .java to run.
1.java set up server connection, connect client and send request, initiate variables with correct values and pass them to the function A, catch the answer and analyse it
2.java set up server connection, connect client and send request, initiate all variables with correct values but one with bad value and pass them to function A, catch the answer and analyse it
3.java set up server connection, connect client and send request, initiate all variables with correct values but two with bad values and pass them to function A, catch the answer and analyse it
so you see in three java test files, the most part of them are the same or similar enough and even copy/paste make the job boring and possible to be wrong.
I wonder whether or not I could define test code corresponding different behavior, then for every test java file, I define a text including the behavior and then a mother class who is in charge of loading the text file and assembling the final test java file according to the text file?
Like this:
Text File:
1) set up server
2) connect client
3) send request
4) initiate variables with correct values
5) initiate variables with correct values but one with bad value
6) initiate variables with correct values but two with bad values
7) catch the result and analyse it
Mother.java
1) load Text file
2) create a son.java
3) find the code corresponding the Text file and write them to son.java
Then the coder open son.java at IDE to check syntax, or import or anything conflict then run it.
Is my idea realizable or not? Is there already something similar?
Any information would be appreciated, thanks a millions in advance!
Honestly, this does not sound like a good use case for code generation. Instead of generating a class for each test case, you should implement a more general testing utility which takes the required input as its data and executes the generic testing code based on this data.
From what you write, this would for example be something like a simple base class for a JUnit test:
abstract class AbstractServerDependantTest {
protected Server server;
protected Client client;
#Before
public void setUp() {
server = new Server();
server.start();
client = new Client();
client.connectTo(server);
}
#After
public void tearDpwm() {
client.disconnect();
server.shutDown();
}
}
Now you can write three test classes which inherit from this AbstractServerDependantTest without copy pasting your code.

Example on how to use TFileTransport in Thrift (Client/Server)

Is there anyone who managed to get TFileTransport as a transport layer, to work? I've tried but since there is no documentation (or have I not found it?) for this, I am not able to make it work.
If anyone have been more successful and could provide some sample code, it would be great.
edit:
What I've tried so far:
public class FileThriftServer {
public static void startThriftServer(
ThriftDataBenchmark.Processor<ThriftDataBenchmarkHandler> processor) {
try {
File input = new File("ThriftFile.in");
if(!input.exists()){
input.createNewFile();
}
File output = new File("ThriftFile.out");
if(!output.exists()){
output.createNewFile();
}
TFileTransport inputFileTransport = new TFileTransport(input.getAbsolutePath(), true);
TFileTransport outputFileTransport = new TFileTransport(output.getAbsolutePath(), false);
inputFileTransport.open();
outputFileTransport.open();
TFileProcessor fProcessor =
new TFileProcessor(processor, new TJSONProtocol.Factory(), inputFileTransport, outputFileTransport);
// this results in error in case I don't call those open methods above
fProcessor.processChunk();
System.out.println("File Thrift service started ...");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// ThriftDataBenchmarkHandler is an implementation of my test service
startThriftServer(new ThriftDataBenchmark.Processor<ThriftDataBenchmarkHandler>(
new ThriftDataBenchmarkHandler()));
}
}
Now I don't know if I am even on a good way, maybe I misunderstood the concept of this transport (again, it is not documented). I would expect I start the server by some method now which will listen on the input file. When clients put there something, it would process it and write the answer to output file (I didn't try to write client yet since this peace of code just executes and exists, it is obviously not right).
edit 2:
Ok, so if I understand it right, this code is ok and it should process one request of the client, if it's there. So I am moving to the client side, doing something like this:
File input = new File(THRIFT_INPUT_FILE_PATH);
if (!input.exists()) {
input.createNewFile();
}
TTransport transport = new TFileTransport(input.getAbsolutePath(),
false);
TProtocol protocol = new TJSONProtocol(transport);
ThriftDataBenchmark.Client client = new ThriftDataBenchmark.Client(
protocol);
// my testing service, the parameters are not important
SimpleCompany company = client.getSimpleCompanyData("token", 42);
Unfortunatelly calling getSimpleCompanyData results in:
org.apache.thrift.transport.TTransportException: Not Supported
at org.apache.thrift.transport.TFileTransport.write(TFileTransport.java:572)
at org.apache.thrift.transport.TTransport.write(TTransport.java:105)
at org.apache.thrift.protocol.TJSONProtocol.writeJSONArrayStart(TJSONProtocol.java:476)
at org.apache.thrift.protocol.TJSONProtocol.writeMessageBegin(TJSONProtocol.java:487)
at org.apache.thrift.TServiceClient.sendBase(TServiceClient.java:62)
It's a bit confusing that server side requires input and output transport but on the client side, it only accepts one. How does it read an answer and from where?
Let's not move into some extra logic of checking the file for changes, if it's not already part of Thrift. I'll be ok at this point by doing it manually in sense of: running the client first, then running the server side.
I would expect I start the server by some method now which will listen on the input file. When clients put there something, it would process it and write the answer to output file (I didn't try to write client yet since this peace of code just executes and exists, it is obviously not right).
That's exactly right. In particular, the fProcessor.processChunk() call you used will process exactly one chunk (the current one). The whole class looks as designed around the assumption that the file size is static and does not change over time. However, the underlying TFileTransport supports what's called a tailPolicy, used when a read call hits EOF:
public class TFileTransport extends TTransport {
public static enum tailPolicy {
NOWAIT(0, 0),
WAIT_FOREVER(500, -1);
/**
* Time in milliseconds to sleep before next read
* If 0, no sleep
*/
public final int timeout_;
/**
* Number of retries before giving up
* if 0, no retries
* if -1, retry forever
*/
public final int retries_;
// ... ctor ...
}
/**
* Current tailing policy
*/
tailPolicy currentPolicy_ = tailPolicy.NOWAIT;
Another option to get it to work could be calling fProcessor.processChunk(int chunkNum), watching the file contents separately and repeat the calls when new data come in. It's certainly not such a bad idea to use the TFileProcessor as a starting point and improve it as needed.
// this results in error in case I don't call those open methods above
fProcessor.processChunk();
Opening the transports before using is fine. I think that part is ok.
org.apache.thrift.transport.TTransportException: Not Supported
at org.apache.thrift.transport.TFileTransport.write(TFileTransport.java:572)
at org.apache.thrift.transport.TTransport.write(TTransport.java:105)
Unfortunately, that seems pretty correct yet. The only place where writing is implemented is the code in the C++ library. Both Java and D only support reading (yet).

what does here_now(String args0) in Pubnub do?

I am trying to find the clients subscribed to a particulair channel. On git I found an example which used a function here_now() with 2 parameters. Something like this:
pubnub.hereNow(channel, new Callback() {
public void successCallback(String channel,Object message) {
notifyUser("HERE NOW : " + message);
}
public void errorCallback(String channel,
Object message) {
notifyUser("HERE NOW : " + message);
}
});
But in my company's application the here_now() function takes only one parameter i.e a String. I am relatively new to pubnub. Can anyone explain me what this parameter is? is it a channel name? how do I specify the call back functions? I am not able to find any documentation related to here_now(String arg)
Thanks
Please run the PubNubDemoConsole.java... you can walk through how all the API calls work.
Specifically, for here_now():
https://github.com/pubnub/java/blob/master/java/examples/src/com/pubnub/examples/PubnubDemoConsole.java#L157
(Looks a lot like above :)
You are indeed passing it two arguments. The first is the channel name you want stats for, the second parameter is the callback function to deliver the success or error results on.
Be sure you are on the latest PubNub for Java version as well:
https://github.com/pubnub/java/blob/master/java
If there are additional questions, let us know here, or via support at pubnub.com
geremy

Play Framework await() makes the application act wierd

I am having some strange trouble with the method await(Future future) of the Controller.
Whenever I add an await line anywhere in my code, some GenericModels which have nothing to do with where I placed await, start loading incorrectly and I can not access to any of their attributes.
The wierdest thing is that if I change something in another completely different java file anywhere in the project, play will try to recompile I guess and in that moment it starts working perfectly, until I clean tmp again.
When you use await in a controller it does bytecode enhancement to break a single method into two threads. This is pretty cool, but definitely one of the 'black magic' tricks of Play1. But, this is one place where Play often acts weird and requires a restart (or as you found, some code changing) - the other place it can act strange is when you change a Model class.
http://www.playframework.com/documentation/1.2.5/asynchronous#SuspendingHTTPrequests
To make it easier to deal with asynchronous code we have introduced
continuations. Continuations allow your code to be suspended and
resumed transparently. So you write your code in a very imperative
way, as:
public static void computeSomething() {
Promise delayedResult = veryLongComputation(…);
String result = await(delayedResult);
render(result); }
In fact here, your code will be executed in 2 steps, in 2 different hreads. But as you see it, it’s very
transparent for your application code.
Using await(…) and continuations, you could write a loop:
public static void loopWithoutBlocking() {
for(int i=0; i<=10; i++) {
Logger.info(i);
await("1s");
}
renderText("Loop finished"); }
And using only 1 thread (which is the default in development mode) to process requests, Play is able to
run concurrently these loops for several requests at the same time.
To respond to your comment:
public static void generatePDF(Long reportId) {
Promise<InputStream> pdf = new ReportAsPDFJob(report).now();
InputStream pdfStream = await(pdf);
renderBinary(pdfStream);
and ReportAsPDFJob is simply a play Job class with doJobWithResult overridden - so it returns the object. See http://www.playframework.com/documentation/1.2.5/jobs for more on jobs.
Calling job.now() returns a future/promise, which you can use like this: await(job.now())

Categories

Resources