Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
HFX
Nov 29, 2004

The Laplace Demon posted:

The answer is to wrap it in a ThreadLocal, please nobody write yet another lovely date formatter for somebody else to maintain.

Java code:
private static final ThreadLocal<SimpleDateFormat> DATE_FORMATTER = new ThreadLocal<SimpleDateFormat>() {
    @Override
    protected SimpleDateFormat initialValue() {
        return new SimpleDateFormat();
    }
};

I am trying to think of one good reason that they class could not be updated to a new version which maintains the interface but doesn't have the state issue. The only issue I can come up with is that someone sub classed it out there. Maybe it would be a good idea to add first class versioning to class binaries. Would also solve the dependency hell I occasionally go through.

Adbot
ADBOT LOVES YOU

hooah
Feb 6, 2006
WTF?
I'm going through these Java koans for kicks, and came upon this one that I can't get to pass:

Java code:
@Koan
public void floatsHaveASmallerRangeThanDoubles() {
    assertEquals(Float.MIN_VALUE, 0x0.000002P-126f);
    assertEquals(Float.MAX_VALUE, 0x1.fffffep127);
}
The koan engine is fine with the MIN_VALUE assertion, but complains about the MAX_VALUE one, saying "expected:<3.4028235E38> but was:<3.4028234663852886E38>". I literally copied the value from the language documentation (https://docs.oracle.com/javase/7/docs/api/java/lang/Float.html#MAX_VALUE). I also tried chopping down what I entered to "3.4028235E38", but it still isn't happy. What gives?

Carbon dioxide
Oct 9, 2012

hooah posted:

I'm going through these Java koans for kicks, and came upon this one that I can't get to pass:

Java code:
@Koan
public void floatsHaveASmallerRangeThanDoubles() {
    assertEquals(Float.MIN_VALUE, 0x0.000002P-126f);
    assertEquals(Float.MAX_VALUE, 0x1.fffffep127);
}
The koan engine is fine with the MIN_VALUE assertion, but complains about the MAX_VALUE one, saying "expected:<3.4028235E38> but was:<3.4028234663852886E38>". I literally copied the value from the language documentation (https://docs.oracle.com/javase/7/docs/api/java/lang/Float.html#MAX_VALUE). I also tried chopping down what I entered to "3.4028235E38", but it still isn't happy. What gives?

You don't have an f at the end of the floating point literal in the MAX_VALUE assert. A floating point literal without an f is always treated as a double, so you're comparing a double precision value against the single precision value in Float.MAX_VALUE.

Also this is literally the first time I've seen hexadecimal floating point literals in Java code.

hooah
Feb 6, 2006
WTF?

Carbon dioxide posted:

You don't have an f at the end of the floating point literal in the MAX_VALUE assert.
:doh:

Carbon dioxide posted:

Also this is literally the first time I've seen hexadecimal floating point literals in Java code.

Yeah, same here. But I was like "gently caress if I remember the IEEE float/double spec, so I'm just going to copy that poo poo". I guess that's what I get for doing that when tired.

hooah
Feb 6, 2006
WTF?
Ok, another question on these koans, this time on streams. Here, the variable str is a global variable, a String initialized as empty. Why is it still empty after the stream is processed?

Java code:
public void lazyEvaluation() {
    Stream stream = places.stream()
            .filter(s -> {
                str = "hello";
                return s.startsWith("S");
             });
    assertEquals(str, "");
}

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

Without having an authoritative answer, my guess is your lambda isn't run at all, yet. Considering it's called "lazyEvaluation", stream objects may not apply the operation until you go to use the result, which is what lazy evaluation is if you aren't familiar. So if you were to reduce() that stream or convert it to an array or whatever, then str would change.

carry on then fucked around with this message at 02:33 on Jul 25, 2017

JewKiller 3000
Nov 28, 2006

by Lowtax
The poster above me is correct, but here is an excerpt from the java.util.stream documentation that might make it clearer:

quote:

Stream operations are divided into intermediate and terminal operations, and are combined to form stream pipelines. A stream pipeline consists of a source (such as a Collection, an array, a generator function, or an I/O channel); followed by zero or more intermediate operations such as Stream.filter or Stream.map; and a terminal operation such as Stream.forEach or Stream.reduce.

Intermediate operations return a new stream. They are always lazy; executing an intermediate operation such as filter() does not actually perform any filtering, but instead creates a new stream that, when traversed, contains the elements of the initial stream that match the given predicate. Traversal of the pipeline source does not begin until the terminal operation of the pipeline is executed.

So basically, because this stream pipeline doesn't have a terminal operation at the end of it, the lambda has not actually been executed yet.

The Laplace Demon
Jul 23, 2009

"Oh dear! Oh dear! Heisenberg is a douche!"
To elaborate further, mutating a field inside a lambda passed to a Stream is a moral failure and you will be reported.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Can you even do that? I thought closures were only over 'effectively final' variables

The Laplace Demon
Jul 23, 2009

"Oh dear! Oh dear! Heisenberg is a douche!"
this is effectively final. this.str is fair game.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

Ohhh a field in the class. That's dark

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

The Laplace Demon posted:

To elaborate further, mutating a field inside a lambda passed to a Stream is a moral failure and you will be reported.

https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html

quote:

Consumer is expected to operate via side-effects.

Where is your god now? :unsmigghh:

hooah
Feb 6, 2006
WTF?
Thanks for the explanations.

Woebin
Feb 6, 2006

At my job we currently update certain database entries by sending PATCH or PUT requests via Postman, which is of course a terrible solution, and a lot of folks here don't know how to do that. So while we're working on a proper solution that's taking a bit of time I threw together a basic Java GUI for sending these same requests via Postman's command line variant, Newman. It works great in Windows and saves a ton of time while eliminating a lot of common mistakes, but I haven't managed to get it working on Macs (probably also on Linux machines, but I haven't tested because the people using Linux are generally too busy developing stuff to update these entries, just like I should be). Here's what I've got that's relevant:
code:
   private void makeNewmanRequest(String input, String output) {
        String stuffToSend = "newman run " + input + " --reporters cli,json --reporter-json-export " + output;
        try {
            Process pr;
            if (os.startsWith("Windows")) {
                pr = Runtime.getRuntime().exec("cmd /c start cmd.exe /K" + stuffToSend);
            } else {
                pr = Runtime.getRuntime().exec(stuffToSend);
            }
            BufferedReader processOutput = new BufferedReader(new InputStreamReader(pr.getInputStream()));
            BufferedWriter processInput = new BufferedWriter(new OutputStreamWriter(pr.getOutputStream()));
            processInput.write(stuffToSend);
            processInput.flush();
            processInput.close();
            processOutput.close();
            pr.waitFor();
        } catch (Exception x) {
            x.printStackTrace();
            JOptionPane.showMessageDialog(null, x.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
    }
When this runs in Windows it brings up a console window and sends the request as intended, everything works, but for the one person I've gotten to try it on Mac the result is an error:
code:
Cannot run program "newman": error=2, No such file or directory
Any thoughts on how to get it working on other machines?

(also I know my code probably looks bad in general, but this is just a placeholder solution anyway)

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
cmd doesn't exist on OS X...

CPColin
Sep 9, 2003

Big ol' smile.
That's what the else is for.

My guess is that newman isn't in the user's path. Does it run from a terminal? You might have to start a shell and tell the shell to run it, similar to how you're starting cmd and using that to run newman. Either way, you probably won't get a terminal window, unless you explicitly start a terminal, too.

Carbon dioxide
Oct 9, 2012

Speaking of HTTP PATCH, we would like to use it in our java REST API (which uses the jackson serializer).

The problem is that with PATCH, according to the standard, if a field in the json does not exist, that means do not update it. If a field is explicitly given as field: null, empty the field in the database. That's nice and all, but of course jackson deserializes both non-existing fields and fields given as null to be null in our java model.

We've been searching online for a solution but didn't find anything that didn't seem incredibly convoluted. The conclusion seems to be that Java simply isn't made to deal with the difference between non-existing and null. If anyone got any suggestions for this one I'd love to hear them.

Volguus
Mar 3, 2009

Carbon dioxide posted:

Speaking of HTTP PATCH, we would like to use it in our java REST API (which uses the jackson serializer).

The problem is that with PATCH, according to the standard, if a field in the json does not exist, that means do not update it. If a field is explicitly given as field: null, empty the field in the database. That's nice and all, but of course jackson deserializes both non-existing fields and fields given as null to be null in our java model.

We've been searching online for a solution but didn't find anything that didn't seem incredibly convoluted. The conclusion seems to be that Java simply isn't made to deal with the difference between non-existing and null. If anyone got any suggestions for this one I'd love to hear them.
I don't think java works that way at all. And "if a field in the json does not exist, that means do not update it. " is a DailyWTF worthy submission. And no, in Java there is no such thing as "non-existing". Yes, javascript has the concept of undefined and null, but that's a different language, aimed at a different audience, which had (originally) a completely different purpose than the things it is used for today.

However, back to your problem:

Solution 1: Send all the fields of the object with the values they will have. Yes, all will be updated and that's the way it should be. You don't get to update "half an object" that's just insane (also means PUT).
Solution 2 (somewhat wrong, but if you insist on using PATCH): Don't tell jackson to deserialize to the object, but do it manually, via the json objects. In there then you can inspect what fields do exist and what values they do have.
Solution 3 (wrong): Also send a list with the fields that you want updated in your json (csv, whatever, you're in "we hack, don't think" territory now). Look at that list and then decide what fields to update in the database (possibly via reflection?)

Woebin posted:

words...

So you replaced an HTTP endpoint call, which can be used straight from java, with which you have 100% control over, with a solution that involves creating a new process, and which is OS-dependent and that you have 0% control over? How do you know if it worked? Parse the output? Look at the return code? Why? And ... what is Postman and why do you need it to update a database?

Volguus fucked around with this message at 18:38 on Aug 2, 2017

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

Woebin posted:

At my job we currently update certain database entries by sending PATCH or PUT requests via Postman, which is of course a terrible solution, and a lot of folks here don't know how to do that. So while we're working on a proper solution that's taking a bit of time I threw together a basic Java GUI for sending these same requests via Postman's command line variant, Newman.

If you are doing it in Java, there's no reason to exec out to some command line REST client. Just use a Java REST library directly.

ulmont
Sep 15, 2010

IF I EVER MISS VOTING IN AN ELECTION (EVEN AMERICAN IDOL) ,OR HAVE UNPAID PARKING TICKETS, PLEASE TAKE AWAY MY FRANCHISE

CPColin posted:

That's what the else is for.

My guess is that newman isn't in the user's path. Does it run from a terminal? You might have to start a shell and tell the shell to run it, similar to how you're starting cmd and using that to run newman. Either way, you probably won't get a terminal window, unless you explicitly start a terminal, too.

Relevant link:
https://stackoverflow.com/questions/4726001/how-to-run-mac-os-terminal-commands-from-java-using-runtime

Carbon dioxide
Oct 9, 2012

Volguus posted:

Solution 1: Send all the fields of the object with the values they will have. Yes, all will be updated and that's the way it should be. You don't get to update "half an object" that's just insane (also means PUT).

Yeah the thing is we got POST to create new documents in the db, PUT to update existing ones in which case you need to give all fields of the object, and we want PATCH to, indeed, update half an object.

One of our usecases for that is that we have a secondary application that we sadly need to keep running for a while to keep our db in sync with some legacy database that's still used by many parts of the company. That application listens to event notifications from the legacy db, and if it gets one, it reads the data from the legacy db, maps it to our model, and sends it to our primary app's rest endpoint to update our db.

But we're now expanding our documents/models with new fields that logically belong in them, so that the parts of the company that have already migrated to our db can use those new fields even though they can't be stored in the legacy system.

The problem this leads to is that the syncing application needs to do a GET on our db to get the non-synced fields, and map those into the update request as well. If it wouldn't do that it would just overwrite the non-synced fields and that would be bad. This means the syncing app needs to have full knowledge of the non-synced fields which doesn't help for maintainability.

Carbon dioxide fucked around with this message at 20:08 on Aug 2, 2017

Woebin
Feb 6, 2006

Volguus posted:

So you replaced an HTTP endpoint call, which can be used straight from java, with which you have 100% control over, with a solution that involves creating a new process, and which is OS-dependent and that you have 0% control over? How do you know if it worked? Parse the output? Look at the return code? Why? And ... what is Postman and why do you need it to update a database?

fletcher posted:

If you are doing it in Java, there's no reason to exec out to some command line REST client. Just use a Java REST library directly.
The reason I did it this way is that I'm honestly a pretty scrub level programmer and this meant not having to write my own REST stuff since I could use the stuff already formulated for this purpose by some guy who left the company. The thing I made just reads Postman collection files, changes some placeholder values to what the user specifies and sends the request via Newman - it was just easier than doing it properly, and as I mentioned a real solution is in progress anyway. I could've learned to do it right but it would've taken longer, so I didn't bother for the time being.

Postman (and Newman) is a tool for making and sending API requests, and is supposed to help with the development of these. I phrased things poorly before, we're not sending stuff directly to the database via REST requests, we're sending them to the API and that deals with the database. I hope this answers your question without making me seem as dumb as I feel.

Thanks, I think I used that for some earlier attempts, but I didn't get it working outside Windows then either. The current thing that tries to account for different OS:es is pretty much straight from a StackOverflow thread, too.

Volguus
Mar 3, 2009

Carbon dioxide posted:

Yeah the thing is we got POST to create new documents in the db, PUT to update existing ones in which case you need to give all fields of the object, and we want PATCH to, indeed, update half an object.

One of our usecases for that is that we have a secondary application that we sadly need to keep running for a while to keep our db in sync with some legacy database that's still used by many parts of the company. That application listens to event notifications from the legacy db, and if it gets one, it reads the data from the legacy db, maps it to our model, and sends it to our primary app's rest endpoint to update our db.

But we're now expanding our documents/models with new fields that logically belong in them, so that the parts of the company that have already migrated to our db can use those new fields even though they can't be stored in the legacy system.

The problem this leads to is that the syncing application needs to do a GET on our db to get the non-synced fields, and map those into the update request as well. If it wouldn't do that it would just overwrite the non-synced fields and that would be bad. This means the syncing app needs to have full knowledge of the non-synced fields which doesn't help for maintainability.

Then you have to "deserialize" manually from the library. You cannot just tell it to give you a full object. For example: mapper.readValue(source, JsonNode.class); Then just look in that node and see what's available. Again, you'll have to be careful with any ORMs (if you're using any), on how do you merge the 2 objects (from the client and from the database).

Edit:
While waiting for my stuff to upload "to the cloud" I thought of maybe another way (more complicated):

A service that can have a generic method something like: "merge<T>(T obj, JsonNode from)", and inside via reflection could update fields in the obj based on what the JsonNode has. Shouldn't be too bad to write, but of course ... reflection.

Volguus fucked around with this message at 23:47 on Aug 2, 2017

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

Woebin posted:

The reason I did it this way is that I'm honestly a pretty scrub level programmer and this meant not having to write my own REST stuff since I could use the stuff already formulated for this purpose by some guy who left the company.

Got it, makes sense that you went down that route then.

I would say take a stab at doing the REST calls in Java - it's probably not as bad as you think it will be. People in this thread can help along the way!

John F Bennett
Jan 30, 2013

I always wear my wedding ring. It's my trademark.

Has anyone here done something with Kotlin yet? Or tried to convert an existing Java project to Kotlin?

M31
Jun 12, 2012

Carbon dioxide posted:

Speaking of HTTP PATCH, we would like to use it in our java REST API (which uses the jackson serializer).

The problem is that with PATCH, according to the standard, if a field in the json does not exist, that means do not update it. If a field is explicitly given as field: null, empty the field in the database. That's nice and all, but of course jackson deserializes both non-existing fields and fields given as null to be null in our java model.

We've been searching online for a solution but didn't find anything that didn't seem incredibly convoluted. The conclusion seems to be that Java simply isn't made to deal with the difference between non-existing and null. If anyone got any suggestions for this one I'd love to hear them.

Is there a PATCH standard? I thought that was up to the implementation.

But if you are using Jackson: mapper.readerForUpdating(object).readValue(json) will update only the specified fields on an object. You will need to fetch the existing data for it to make any sense though. Another way is abusing Optional<> fields so you get null if no value was specified, and Optional.empty() when a null value is provided. Then you can do whatever you want afterwards.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

John F Bennett posted:

Has anyone here done something with Kotlin yet? Or tried to convert an existing Java project to Kotlin?

Only doing stuff with Awful.apk but yeah, it's neat. Still getting my head around the organisation and stuff, I'm just starting out with it really. I feel like it's gonna scratch that functional itch though

Carbon dioxide
Oct 9, 2012

M31 posted:

Is there a PATCH standard? I thought that was up to the implementation.

But if you are using Jackson: mapper.readerForUpdating(object).readValue(json) will update only the specified fields on an object. You will need to fetch the existing data for it to make any sense though. Another way is abusing Optional<> fields so you get null if no value was specified, and Optional.empty() when a null value is provided. Then you can do whatever you want afterwards.

Hey that readerForUpdating is a great suggestion, that might be what I'm looking for. I'll try it out, thanks!

JewKiller 3000
Nov 28, 2006

by Lowtax
Update on Java 8 streams usage in my project: this poo poo is very good. I am actually using the parallelStream() feature now, and when I launch an AWS instance with more vCPUs it just scales automatically, I don't have to manipulate threads anywhere. I realize many people don't like the parallel streams because of how they interact with other things, but in my case I have no other things (this is a bulk job which just runs my program in a Docker image and does nothing else). There is not a single for loop in my project now. :getin: Highly recommended!

venutolo
Jun 4, 2003

Dinosaur Gum
Does anyone happen to know of a Java library (or anything else we could make use of from an application) that would attempt to properly capitalize text according to various languages' mechanics? Such as something would allow me to feed in "the count of monte cristo" and "English" and get back "The Count of Monte Cristo".

geeves
Sep 16, 2004

venutolo posted:

Does anyone happen to know of a Java library (or anything else we could make use of from an application) that would attempt to properly capitalize text according to various languages' mechanics? Such as something would allow me to feed in "the count of monte cristo" and "English" and get back "The Count of Monte Cristo".

The closest I can think of is apache commons' WordUtils.

But if you wanted to catch the "unimportant" words like "of", "a", etc. that are not first or last, you're probably off better writing something that watches for those so you can skip them depending on their placement, but even then it might not be perfect and WordUtils.capitalizeFully could be close enough for your needs.

venutolo
Jun 4, 2003

Dinosaur Gum

geeves posted:

The closest I can think of is apache commons' WordUtils.

But if you wanted to catch the "unimportant" words like "of", "a", etc. that are not first or last, you're probably off better writing something that watches for those so you can skip them depending on their placement, but even then it might not be perfect and WordUtils.capitalizeFully could be close enough for your needs.

Thanks. I'm looking for something that would work across multiple different languages, not just English, and wouldn't require us to know whatever rules of that language.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

That's not a 'rule' of English though, it's just a style guide. Plus with that example you have a couple of authorities, one that tells you how to capitalise book titles, and one that tells you how to refer to members of a particular titled hierarchy. And when you get into other languages with other capitalisation rules it starts to get a bit spicy

It's a pretty human thing, i.e. it's a bit complicated and an automagical library probably doesn't exist. If you're lucky there might be a locale-aware one that can do basic title case

FAT32 SHAMER
Aug 16, 2012



Someone reading itt just found their thesis though so goongrats hope it works out for you

Pedestrian Xing
Jul 19, 2007

Any recommendations for a printing library? I want to take an image file, a dynamic printer address, and have it print with minimal configuration.

Volguus
Mar 3, 2009

Pedestrian Xing posted:

Any recommendations for a printing library? I want to take an image file, a dynamic printer address, and have it print with minimal configuration.

Have you tried java.print and/or javax.print? If you did, was there a problem with them?

Hughlander
May 11, 2005

Stupid question that's been bugging me.

Has anyone seen a library/program to talk to a gradle daemon running and let you kick off tasks and see their status just by hitting a localhost port? I have a poo poo ton of utility tasks that I'd like to just have a browser window open in the corner and click rather than find the right terminal window and type a long rear end task name. Secondary is there a good IntelliJ plugin to run tasks? For whatever reason the built in Run Gradle Task doesn't show the tasks for my project.

poemdexter
Feb 18, 2005

Hooray Indie Games!

College Slice

Hughlander posted:

Stupid question that's been bugging me.

Has anyone seen a library/program to talk to a gradle daemon running and let you kick off tasks and see their status just by hitting a localhost port? I have a poo poo ton of utility tasks that I'd like to just have a browser window open in the corner and click rather than find the right terminal window and type a long rear end task name. Secondary is there a good IntelliJ plugin to run tasks? For whatever reason the built in Run Gradle Task doesn't show the tasks for my project.

When you import your project, don't navigate just to the directory. Instead navigate all the way to the build.gradle file. That will set up your project as a gradle project. From the gradle tab thing on the right, you'll be able to see all your tasks and you can double click them to run them. This is built into intellij and you don't really need a plugin.

Stabbey_the_Clown
Sep 21, 2002

Are... are you quite sure you really want to say that?
Taco Defender
I'm trying to call a static method inside a class which does not have an instance instantiated in it. (It's a message services routine intended to pass information messages, errors, warnings, debug messages to standard out and/or a logfile.)

This class contains an enum, and I want to compare a value passed into the method to see which value of the enum it matches. The problem is that (apparently) because the class hasn't been instantiated, all the values of the enum are zero. Is there some way I can get the proper value of the enum to be seen (preferably from outside the class as well)?

Adbot
ADBOT LOVES YOU

CPColin
Sep 9, 2003

Big ol' smile.
That sounds like you've got some crazy interaction going on where the class hasn't fully loaded and is trying to reference itself, or something. Defining the enum somewhere besides in that class might help break whatever weird initialization path is going on. Otherwise, could you give a little more context on how the code is laid out?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply