How to receive a multipart message in ZMQ using Java? - java

As simple as this operation seems I can't find any documentation regarding how to receive a multipart message using ZMQ (Jeromq). I checked The Guide but it only contains C code with this info and it seems that I'm supposed to receive messages the same way no matter what kind of message I'm receiving.
In reality what happens is that I receive the multipart message in two messages with this code:
while (running.get()) {
items.poll();
if (items.pollin(0)) {
ByteArray message = receiver.recv(0);
System.out.println("Received " + String(message, Charset.forName("UTF-8")));
}
}
The "Received" part will get printed twice if I send a multipart message like this:
publisher.sendMore(message.key);
publisher.send(objectMapper.writeValueAsString(message.data));
What am I doing wrong?
Edit: I know there is a language selector below the examples but this particular problem is not present in any of the examples only explained inline with C code.
Edit
I tried to explore the API and found the hasReceiveMore() method. I tried using it, but it didn't work, I ended up with an infinite loop with this code:
List<String> parts = new ArrayList<>();
while(receiver.hasReceiveMore()) {
parts.add(receiver.recvStr());
}

Q : "What am I doing wrong?"
Your code has to actively assume each message to might have been composed as a multipart-message (Zero-Warranties in this, the less a-priori) and actively check for the presence of the ZMQ_RECVMORE flag, after each subsequent .recv()-method call, until the .getsockopt( ZMQ_RECVMORE )-method says otherwise.
JeroMQ might have translated this published native-API into some other utlity methods, so best re-read the JeroMQ-source code to find, where this native-API multipart-message handling-"protocol" gets wrapped into the JeroMQ-tooling.
EPILOGUE : Verba docent, Exempla trahunt...Having helped more than 1.3 M Community members and countless anonymous site visitors, I got punished and censored for helping.Censorship of deleting comments continues. The spirit of StackOverflow turns to digital totalitarianism. Delete, delete and punish those, who keep thinking and present help and advice to those, who ask for a sponsored help...-------------------------------------Let's review the facts:-----"I couldn't find any docs regarding how I should receive the parts, but I tried something that looks like what you mentioned...it didn't work either. – Adam Arold 20 hours ago"Either of not finding "any docs" or a "not working" (another not published, reproducible MCVE) were my fault or omission, were they?( my answer to these false claims was administratively deleted a few minutes after being posted... Self-explanatory )-----"This is not an answer and it doesn't contain a solution. I'm not sure why you're surprised. What you cited is the C API that has nothing to do with the JeroMQ API. In the end the solution was that I have to recv before I try to check the RECVMORE flag. This was not in your answer. Alternatively ZMsg can be used. – Adam Arold 11 hours ago"ANALYSIS OF THE CLAIMS :Sentence #1. :"This is not an answer and it doesn't contain a solution."This IS an answer, in spite of the "claim". It contains several important pieces of information, that she/he/anyone would otherwise have to try to seek for hours (days or weeks?) to later study and conceptually well comprehend architecture-wise so as not to make any ill-formulated code-design(s) or get principally trapped into one's own, misconcepted, decisions, if not having been advised and warned about thses possible shortcommings I've personally met ( and help others not to repeat ) throughout my last 13+ years spent with fabulous Martin Sustrik's masterpiece - the ZeroMQ, since v2.1+. So this "claim" is both wrong and unsupported by facts. A minor "claim" that the answer did not contain a solution is absurd, StackOverflow Community members are neither an employee to shout at, the less we bear a commitment to program a code that will snap and fit all the needs of the (unpublished) use-case.Sentence #2 :(an expressed feeling)- rather skipped as it is more a case of insult than a fair argument, isn't it?Sentence #3 :"What you cited is the C API that has nothing to do with the JeroMQ API."Oh sure, YES , the C API ( and the ZeroMQ-RFC docs on mandatory "wire-line" protocols properties that any peer-implementation has to obey... ) is the starting point and a cardinal reference in all of this. And NO , both the published ZeroMQ RFC-documents and the API are the rock-solid reference for anyone to start with, so as to best understand, how the internal engines and all the mandatory "wire-line" properties obeying protocol pumps are working (and must be working), so as to declare themselves to retain the ZeroMQ-compatibility. The JeroMQ-authors did their work based on these documented properties, didn't they? If they did not or if they "cut some corners" on doing that, the story is lost and was not my fault they did not meet and/or cover all the ZMTP/ZeroMQ-RFC/API properties & requirements, was it? That said, any wrapper/binding, including any version of the JeroMQ must also conform to these inner working rules, which is sufficiently self-documented & demonstrated, if nowhere else, in the JeroMQ source-code (Which warning was also the part of the Answer provided, wasn't it?), if it aspires to be a ZeroMQ-compatible tool. Again, should your current (used) JeroMQ-implementation misses to meet a well documented JeroMQ-API documentation you would like to use & read through (to find both the description and examples of code for the use-cases), which was claimed it did not or that the will to seek and find any such (source-coded) information, it is not the Community sponsoring member to punish for the lack of both the former, the more the latter.Sentence 4. + 5. :This needs to get highlighted:"In the end the solution was that I have to recv before I try to check the RECVMORE flag. This was not in your answer."First of all, it WAS in the Answer - the very first sentence:"...code has to actively assume each message to might have been composed as a multipart-message (Zero-Warranties in this, the less a-priori) and actively check for the presence of the ZMQ_RECVMORE flag, after each subsequent .recv()-method call, until the .getsockopt( ZMQ_RECVMORE )-method says otherwise."My generation grew up in a deep belief, that if we've made an error or 've made a poor decision, based on an unsupported assumption, we never punish anyone else, for (us) having made an error of a bad decision. Surprisingly, not working here. Why would anyone ever punish a person, who reached out and came to help you solve your problem and sponsored your personal need to get a step further? No one will if the culture to ask for a sponsored help and punish anyone who did would grow further. Isn't this called an arrogant or dictator-alike style of person to person behaviour? Be it the former or latter, it is neither fair, the less a style to be promoted the less rewarded as a Community preferred behaviour. The "argument" per se is empty, void - Not having called a .recv()-method, nothing gets ever from inside the ZeroMQ-API abstract horizon, the less an indication, promised to learn by .getsockopt()-method's use on getting a RECVMORE-flag ( sure, after some .recv() has been confirmed to have gotten a substance --The-Message-- That is both elementary and does not need to "include" it in any text about ZeroMQ/JeroMQ messaging as it is self-explanatory - Would anyone claim that it was unfair not to explain that asking for an email-attachment makes no sense if there were no email delivered so far? No one fair ever would. So, the Answer did the very opposite - it did warn about this, that for every .recv()-ed message, professional designer ought always assume a { 0+ }-RECVMORE-flagged multi-part message components, that follow the first one .recv()-ed and need to get dug out of the API.The last sentence :"Alternatively ZMsg can be used."This claim remains an undecidable problem, as the O/P contains zero information about a version. Native ZeroMQ API has evolved since its premiere release via v2.0-v2.1-..-v2.11, via v3.0-v3.1-v3.2, refactored and extended via v4.0-v4.1-v4.2-v4.3 and still counting, and a "claimed" Zmsg-abstraction is sure not to be present in earlier implementations, so the version number is cardinal on this ( also being a part of the StackOverflow best practices for how to ask good questions with a problem-reproducing MCVE / MWE code and all relevant details, the version number being one part of that, isn't it? ).

Related

Why is one user getting NoSuchMethodError where tens of thousands don't?

How can one of our many users get
java.lang.NoSuchMethodError:
at com.mycelium.wallet.activity.settings.SettingsPreference.getLanguage (SettingsPreference.kt:73)
at com.mycelium.wallet.WalletApplication.onCreate (WalletApplication.java:109)
at android.app.Instrumentation.callApplicationOnCreate (Instrumentation.java:1127)
on this line of Kotlin code:
#JvmStatic
fun getLanguage(): String? = sharedPreferences.getString(Constants.LANGUAGE_SETTING, Locale.getDefault().language)
There are three function calls on this line: android.content.SharedPreferences::getString(String,String), java.util.Locale::getDefault() and java.util.Locale::getLanguage() all of which are available since API 1.
The only affected user (Samsung Galaxy A5(2017) (a5y17lte), 2816MB RAM, Android 8.0) tried to start the app 180 times with this insta-crash.
The conversion to Kotlin might have issues still?
try { ... } catch (NoSuchMethodError e) { ... } might be a suitable workaround. But they already might have given up; if you don't have any email address or alike, you won't be able to notify them. You'd could return a static string in case of a NoSuchMethodError. Besides, if one has written down the seed phrase, the wallet is on the block-chain, the device only has the keys. I'd file that as an individual destiny - and that device probably could still be rooted, to have the keys extracted. It's difficult to help them without having a support request, so that one could notify them of a new version, which not relies on whatever unknown method. Maybe they still use it and would receive an auto-update and try again, but only maybe - but there's no guarantee, that this is the only one unknown method on this device.
It's definitely not a Kotlin issue, but rather a storage defect; google "eMMC corruption".
And if the user has not written down their seed phrase, it's their very own fault.
This all is an assumption, but the probability isn't that low.
As you know (I am sure) a NoSuchMethodError is caused by a mismatch between the versions of classes at compile time versus at runtime.
And, I agree with you that the three methods called by that line of code should be present at runtime.
I was a suspicious that there isn't a message string for the NoSuchMethodError to say which method was missing, but there are other examples for the Android platform where the message is missing. So I am (tentatively) calling this not significant.
So we have to look for other explanations. Here are some:
The line number in the stacktrace could be inaccurate. People sometimes report this kind of thing; e.g. Crashlytics is reporting wrong line numbers
This particular user could be running a different (older?) version of your app where the code at that line is different to code you are looking at.
The user has "rooted" his device and messed around with its standard libraries. Alternatively, the user's device has been hacked and the hacker has interfered with the standard libraries (rather crudely in this case).
The user has been messing with the bytecodes for your app and has accidentally got it trying to call a non-existent method. Alternatively, the user is running a (crudely) trojaned version of your app where the bad guy has done the same thing.
The fact that your app involves Bitcoins means that there could be strong incentive for someone to be doing nefarious things ... so the last two alternatives should not be discounted.
The conversion to Kotlin might have issues still?
I don't see why that would affect only one user.
The fact the user tried 180 times is why I care. This is a Bitcoin wallet, so ... they might have money in that wallet and I hate to not fix issues if I can.
(Or conversely, this might be a bad guy trying to get bitcoins out of a wallet via a stolen device. The fact that the user is being so persistent ... and hasn't contacted you for help ... is suspicious in itself.)
But the point is that if you don't have any way to contact this user, fixing the issue in general is unlikely to help them directly. And right now you don't have enough information to know what the problem really is.

How to connect java and Adf.ly?

Is there any way in java to make code: Example if someone clicks on skipAd on adf.ly link Int will increase. Example 2: I click the button, it will take me to a adfly link. and when i click skipAd on adf.ly: in the app int will increase for 1(int++).
Is there any way to do that?
First of: StackOverflow hates it when people come here showing that they have taken zero effort to find a solution for the problem.
Secondly:
Your question is very unspecific.
Are you and your friend on the same network? If so, you might want to consider using ARP-Poisoning in order to inject custom JavaScript into the webpage that will function as an EventListener. Obviously this will only work if he is visiting AdFly via an HTTP connection and since Adfly-Links are generated with an HTTPS prefix, you will rarely find people using HTTP (despite the fact that they still don't enforce HTTPS, grumpf).
There are probably tons of other solutions but they will all involve tinkering with his/your webtraffic. And no offense, but I feel like you should probably learn some more Java before taking on such a big task.
More than in 'java' it would be easier to do it in 'JavaScript'. You'll have to monitor the onClick event of that SkipAd button and then you can increase your counter.
I advise you to make your question even more clearer in why-you-have-to-do-it department to avoid down votes

Is it a good practice to log line number in error code to the user?

I have been tasked with logging the line number as part of the error code shown to the user. Currently I am using:
StackTraceElement[] stackTraceElement = e.getStackTrace();
lineNumber = stackTraceElement[0].getLineNumber();
I know that the above approach may fail depending on the JVM version.
Also, I have seen the PatternLayout where it is mentioned that "Generating caller location information is extremely slow. Its use should be avoided unless execution speed is not an issue.".
Since this message will be presented to the user, should I still log the line number as part of the error code? I am trying to understand the pros and cons of this approach. Also, does the log4j warning apply only to its own implementation or rather is it a warning against location information generally?
Well, generally speaking your program should report two kind of errors:
The errors that are for the user (when the user is not doing what is expected from him), which should actually be better called "feedback" to help him feed your program with the right data (that's good UX practice).
The errors that are generated because of a bug, which are actually not targeted at the user, but at you the developer, sadly through the user. Then yes, it might be a good idea to log line numbers (or give your errors unique names/identifiers so that you can trace easily where it's been sent from). But a better idea is to then use a framework to report such issues directly to you through Internet (good practice being to ask for permission first).
What you should show to the user is what went wrong and what he can do about it, if anything. The line number information needs to be available, e.g. via a 'More details' button, in case he needs to raise a support ticket, but you don't want to frighten him or confuse him with it up front. Just look at how many stack traces get misread or indeed ignored completely here, and this community is supposed to be computer programmers.
Generally its better if your program doesn't give errors, and can receive all input, and give you tips on how to use the application. This will give users a much better experience if you want them to buy your product, etc.. If your program does give errors, it will not be helpful for the user to know the line number. You however will want to know the line number, so you should make it display a message of some sort that tells the user to email you the stack trace when the error occurs. Or you could have it report the error message automatically and email it to you.
Sorry, I'm a bit late I was unclear what the question was asking, so I posted this as a comment, but clearly it is an acceptable answer.

SVNClient.logMessages never returns a result

I'm using JavaHL to connect to a 1.6 svn repos. While I managed to list the contents of the repository, I'm not able to get the item history (the comments made on the check ins as well as the dates and the authors).
As far as I see, SVNClient.logMessages is the right method, but the callback method is never been executed. I used Revision.HEAD for the path revision and a revision range object holding Revision.START and Revision.HEAD; the limit is set to 0 (which is no limit according to the documentation). I'm trying to fetch the revision, the date, the author and the comment.
If someone knows about example code on using JavaHL I'm maybe able to find my fault by comparing that code to mine.
BTW: I know about SVNKit, but the management decided not to buy it. Thus I have to use JavaHL, where next-to-no sample programs exist (and the doc will merely list the classes and interfaces without a very detailed description). So, please point me in that direction of SVNKit as this is impossible for me.
Any pointers appreciated.
Gnarf
The issue has been solved. The problem was the call to SVNClient.logMessages(), especially the revision range used.
The start revision had been Revision.START that, according to the documentation, is used to describe the "first existing revision".
The problem disappeared when I used Revision.getInstance(1) instead. As it is reasonable that any item has at least one revision (the initial one) with that number, it should be save to use that.
Hopefully this will save anyone else from spending another two-and-a-half days to figure it out!
Gnarf

How to webscrape scholar.google.com in Java?

I want to write a Java func grabTopResults(String f) such that grabTopResults("automata theory") returns me a list of the top 100 cited papers on scholar.google.com for "automata theory".
Does anyone have suggestions for what libraries will make my life easy?
Thanks!
As I'm sure Google can afford the bandwidth, I'll ignore the question of whether this is immoral/illegal/prohibited by Google's T&C
First thing you need to do is figure out what HTTP request (or requests) you need to issue in order to obtain the page with the data you need. Once you've figured this out, use HttpClient to issue the same request from Java code. The previous link shows example code that explains how to do this.
Once you've downloaded the content of the relevant page, you'll need to use a HTML parser to extract the data you're interested in. The Jericho parser suggested by peperg is a good choice.
If the Google police come knocking, you've never heard of me, OK?
I use http://jericho.htmlparser.net/docs/index.html . Google Scholar doesn't have API ( http://code.google.com/p/google-ajax-apis/issues/detail?id=109 ). Of course it is not allowed by Google (read terms of use. Automatic requestr are forbidden).
Below is a bit of example code which gets the titles on the first page using the open source product TestPlan. It is a standalone product, but if you really need it I could help you integrated it into your Java code (it is written in Java itself).
GotoURL http://scholar.google.com/
SubmitForm with
%Params:q% automate theory
end
set %Items% as response //div[#class='gs_r']
foreach %Item% in %Items%
set %Title% as selectIn %Item% h3
Notice %Title%
end
This produces output like the below (my IP is Germany, thus a german response). Obviously you could format it however you like, or write it to a file; this is just a rough test.
00000000-00 GOTOURL http://scholar.google.com/
00000001-00 SUBMITFORM default
00000002-00 NOTICE [ZITATION] Stochastic complexity in statistical inquiry theory
00000003-00 NOTICE AUTOMATED THEORY FORMATION IN MATHEMATICS1
00000004-00 NOTICE Constraint generation via automated theory formation
00000005-00 NOTICE [BUCH] Automated theorem proving: after 25 years
00000006-00 NOTICE [BUCH] Introduction to the Theory of Computation
00000007-00 NOTICE [ZITATION] Computer-controlled systems: theory and design
00000008-00 NOTICE [BUCH] … , randomness & incompleteness: papers on algorithmic information theory
00000009-00 NOTICE [BUCH] Automatic control systems
00000010-00 NOTICE [BUCH] VLSI physical design automation: theory and practice
00000011-00 NOTICE Singular Control Systems.

Categories

Resources