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
carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

Xenophanes posted:

Yeah, those were both requirements. After poking at it for about 6 hours I got it to work(?) with
code:
    public MyNode() {
        this.data = null;
        MyNode[] test = new MyNode[26];
        this.children = (MyNode<T>[]) test;
    }
I don't understand how casting it to the generic form after initializing the array works when doing what seems to me to be the same thing in one line doesn't compile, but here's hoping it doesn't cause everything to fall apart down the line. Thanks so much for the help.

This one works because of type erasure. The compiler removes the <T> in your class name and replaces each T with Object, which is incidentally what you get when you declare a MyNode with no type parameter at all. Since MyNode<T> becomes a MyNode at runtime, MyNode[] is allowed to be cast to MyNode<T>[] (with a warning about an unchecked cast being all Java does to let you know about possible problems.) Object is a superclass of MyNode, so you can't cast an Object down to a MyNode unless it is one already behind the scenes (declared as MyNode and then cast upward to Object,) which means you can't cast a new Object[] down to MyNode[] or MyNode<T>.

Java's type safety gets fuzzy when dealing with generics and generics are one of Java's rough edges.

carry on then fucked around with this message at 13:52 on May 5, 2020

Adbot
ADBOT LOVES YOU

Imazul
Sep 3, 2006

This was actually a lot more bearable than most of you made it out to be.
You really should not be doing an array of generic. That is a huge no no of Java. Even if this compile it might do funky stuff at runtime.

Generics are invariant unlike arrays that are polymorphic like carry on then explained in more words. So if you use this inside your class it's probably going to work, if you ever try to use this outside the class you will probably run into a bunch of ClassCastException because the type will still be Object.

Paul MaudDib
May 3, 2006

TEAM NVIDIA:
FORUM POLICE
One of our team members converted our ant build to a gradle build and it seems to ignore build-time exception checking (eg emitting exceptions is not checked).

Any idea what's up with that/a thing I should start looking for?

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

Xenophanes posted:

Yeah, those were both requirements. After poking at it for about 6 hours I got it to work(?) with
code:
    public MyNode() {
        this.data = null;
        MyNode[] test = new MyNode[26];
        this.children = (MyNode<T>[]) test;
    }
I don't understand how casting it to the generic form after initializing the array works when doing what seems to me to be the same thing in one line doesn't compile, but here's hoping it doesn't cause everything to fall apart down the line. Thanks so much for the help.

To add what others have said, generics in Java don't really exist under the hood - your List<String> is really just a raw List that can hold any type (it's a List of Objects). So the generics system is sort of a compile-time contract you're outlining. By specifying your types, the compiler can look at how you're using things - what types you're putting into them, what type you're treating them as when you access them, etc - and complain about any inconsistencies, so you don't end up accessing a type in an illegal way. And one of the ways it enforces that is by preventing you from creating arrays of generic types.

But at the end of the day that's all it is, a checking system where you set out rules and it checks if you look like you're following them. You can still step outside of it by doing things like explicit casting (you get warnings about unchecked casts, because it can't verify what you're doing is correct and valid). At that point, it just has to trust what you're doing - and in your case, your non-generic array of raw MyNode objects can be treated as an array of MyNode<T>, because that's all you're putting in that array. But the generics system can't guarantee that, so you're outside of the type-safety checks and going rogue

Hippie Hedgehog
Feb 19, 2007

Ever cuddled a hedgehog?

Paul MaudDib posted:

One of our team members converted our ant build to a gradle build and it seems to ignore build-time exception checking (eg emitting exceptions is not checked).

Any idea what's up with that/a thing I should start looking for?

Do you mean for unit tests? Like, if a test case throws an exception, it doesn't fail like it should? (I don't know what else part of a build could emit exceptions.) Normally all unit testing frameworks I've heard of should take care of that, unless they're misconfigured or a test case is annotated like it is expected to throw a particular exception...

Twerk from Home
Jan 17, 2009

This avatar brought to you by the 'save our dead gay forums' foundation.
Assigning variables is atomic, right? Long story short, I've got a config provider that needs to be giving other threads a reference to a cached version of a bit of config. It stores this in a private field that is only updated by a specific thread whole job is to update the config.

Many other threads get the config from this provider. When the thread that gets a newer copy of the config to cache does so, it constructs a new object, assigns it to a local variable, and then assigns it to the private field.

My belief when setting this up is that because I have one writer, many readers, AND it's not important that readers ALWAYS get the newest version of what is written, I don't need any synchronization or volatile keyword or anything at all. Is this accurate? Am I setting myself up for mysterious pain down the road?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
The setup as you describe might be safe, but it's very brittle. For example, if any of the fields of your Config object aren't final, then it's not safe. Are you sure that nobody is ever going to introduce a non-final field in any later code changes?

Just make your shared field volatile.

Twerk from Home
Jan 17, 2009

This avatar brought to you by the 'save our dead gay forums' foundation.

Jabor posted:

The setup as you describe might be safe, but it's very brittle. For example, if any of the fields of your Config object aren't final, then it's not safe. Are you sure that nobody is ever going to introduce a non-final field in any later code changes?

Just make your shared field volatile.

They all are. I'm actually using Kotlin and the Config object is a data class, and all fields are val, the equivalent of final. I may go ahead and mark it volatile anyway, to guarantee ordering of reads/writes.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
I hope you have a plan for informing other developers of the requirement to never add any non-final fields. Perhaps a unit test that reflects on the class and makes sure everything is final?

The other thing to keep in mind is that, even if it's an acceptable for a thread to not see the updated value immediately, it's often a requirement that the updated value will eventually be seen at some point. Depending on how the rest of your code is structured, this may not actually be true, and it can be difficult to reason about.

What are you trying to avoid by not using volatile?

Twerk from Home
Jan 17, 2009

This avatar brought to you by the 'save our dead gay forums' foundation.

Jabor posted:

I hope you have a plan for informing other developers of the requirement to never add any non-final fields. Perhaps a unit test that reflects on the class and makes sure everything is final?

The other thing to keep in mind is that, even if it's an acceptable for a thread to not see the updated value immediately, it's often a requirement that the updated value will eventually be seen at some point. Depending on how the rest of your code is structured, this may not actually be true, and it can be difficult to reason about.

What are you trying to avoid by not using volatile?

Honestly? My team and I are either novices or really rusty at dealing with true concurrency issues, and by default fall down the "just add locks until it works". It's pretty clear to me here that we don't need a lock, and I don't have a great understanding of what volatile actually gets you, which is part of why I'm asking here.

If the Config object is marked volatile, will that carry over to all of its fields? If someone does add a mutable field in the future, will volatile carry down to all objects referred to by the Config object, or at that point would we need to synchronize reads anyway?

We've done concurrency in Go more recently, with the general model of "one thread owns writing to any given thing", and are just looking to carry that pattern over to the JVM.

Twerk from Home fucked around with this message at 17:57 on May 15, 2020

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Essentially, the Java memory model defines a partial ordering (called happens-before) on various things that you do in your program. If thing A happens-before thing B, then any thread that observes thing B will subsequently also observe thing A. If there is no happens-before relationship, then you don't get that guarantee.

Some examples of happens-before are that a thread releasing a lock happens-before any other thread takes that same lock. Another example is that a write to a field while a lock is held happens-before that lock is released. When you combine those together, you get the very useful property that if you write something to a field while holding a lock, then release the lock, the next thread to take that lock is guaranteed to see your write.

volatile fields get similar happens-before guarantees - any previous write happens-before the write to a volatile field, and so any thread which sees the new value of the field will also see all the writes you made beforehand. So, it's sufficient to mark the top-level field as volatile - anything that sees the new value of the field will also see all the writes that were made as part of creating the object.

E: if you do want to change individual fields after the object has been made available to other threads, you're back at needing to think carefully about things.

Jabor fucked around with this message at 18:30 on May 15, 2020

Twerk from Home
Jan 17, 2009

This avatar brought to you by the 'save our dead gay forums' foundation.

Jabor posted:

Essentially, the Java memory model defines a partial ordering (called happens-before) on various things that you do in your program. If thing A happens-before thing B, then any thread that observes thing B will subsequently also observe thing A. If there is no happens-before relationship, then you don't get that guarantee.

Some examples of happens-before are that a thread releasing a lock happens-before any other thread takes that same lock. Another example is that a write to a field while a lock is held happens-before that lock is released. When you combine those together, you get the very useful property that if you write something to a field while holding a lock, then release the lock, the next thread to take that lock is guaranteed to see your write.

volatile fields get similar happens-before guarantees - any previous write happens-before the write to a volatile field, and so any thread which sees the new value of the field will also see all the writes you made beforehand. So, it's sufficient to mark the top-level field as volatile - anything that sees the new value of the field will also see all the writes that were made as part of creating the object.

E: if you do want to change individual fields after the object has been made available to other threads, you're back at needing to think carefully about things.

I appreciate this. It seems like the safest thing is to just acquire a lock on the object before updating anything or reading anything, and be done with it.

If we did want no lock and to have mutable fields on the Config object after construction, then those fields would also need to be marked volatile? Assuming still that there is only the one single thread ever writing to it.

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

Yeah volatile effectively marks the variable so that when it's written to, every thread will see the updated value immediately. It's a nice fit for logic where only one thread is writing, and it's a single, isolated operation. Or where you're using a sync block to update a few fields simultaneously, but maybe one of those fields gets read on its own, so those readers don't actually need to synchronize just to read a single value, they just want it to be current

The opposite is a ThreadLocal variable, which is where each thread has its own, isolated copy of a variable, and a change made by one thread will never be reflected in another. Not using any synchronization at all is kinda putting yourself in the mystery space inbetween, where the hardware might cache local values forever, or maybe it'll update them at some point, and debugging issues will become a huge pain when you can't be sure what your actual state is

If you're worried about performance, you should benchmark it and see if it's an actual problem - as far as I'm aware @Volatile is actually pretty lightweight, compared to locking anyway. Also if you're using Kotlin maybe look into coroutines if that's an option - they're like lightweight threads, so if you need that performance they might help

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

Twerk from Home posted:

I appreciate this. It seems like the safest thing is to just acquire a lock on the object before updating anything or reading anything, and be done with it.

If we did want no lock and to have mutable fields on the Config object after construction, then those fields would also need to be marked volatile? Assuming still that there is only the one single thread ever writing to it.

if you have multiple threads, and fields which aren't final, assume writes to those variables by one thread won't be seen by other threads. You have to explicitly guarantee that, either by marking them as volatile, or by accessing them through a synchronized block.

So if you write to the volatile field myObject, everything accessing it will see the latest version - a reference to a particular object. But if the fields in that object are mutable, any changes you make to those values won't necessarily be seen. So you have to use the same approach

This is why immutable state makes things a lot easier - an object is an object, once you can see it you can see it. You don't need to worry about values changing, or race conditions where there are two related values and you happen to get the old value for one and the new value for another. With mutable state you need to look at exactly how stuff will be accessed, what operations you need to make atomic, and plan around that (commenting on concurrency stuff is your friend!)

smackfu
Jun 7, 2004

I have one thread that has to generate a String value every ten minutes, and a bunch of other threads that have to access that value, and also not block while the value is being generated.

I don’t do much manual thread stuff anymore... Is there any more modern way to do this than just throwing the synchronized keyword around a lot?

smackfu fucked around with this message at 01:02 on May 19, 2020

Twerk from Home
Jan 17, 2009

This avatar brought to you by the 'save our dead gay forums' foundation.

smackfu posted:

I have one thread that has to generate a String value every ten minutes, and a bunch of other threads that have to access that value, and also not block while the value is being generated.

I don’t do much manual thread stuff anymore... Is there any more modern way to do this than just throwing the synchronized keyword around a lot?

I believe that’s exactly the scenario I asked about above, so you want to have the member marked volatile and that’s about it as long as there’s only one writer.

smackfu
Jun 7, 2004

Wow, that’s embarrassing proof that I didn’t read the thread before posting. My bad.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Wheany posted:

My most favorite thing about spring boot is configuration parsing. I can add a new configuration option to my externalized config class and then command line options and application.properties just work

Time to repost this again. Still loving it.

Love Stole the Day
Nov 4, 2012
Please give me free quality professional advice so I can be a baby about it and insult you

Wheany posted:

Time to repost this again. Still loving it.

I really like it, too... but I think it sucks that we can't know what config properties are available or required by a new dependency that we add. For example, if I add one of the Spring Cloud starter packages, I cannot run the application unless I set a bunch of config variables that are required by it... but you can't just look up in some obvious place where all of those newly required things live and what they're supposed to be! You just have to hope that the new package has good enough documentation for you to be able to figure it out.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Love Stole the Day posted:

I really like it, too... but I think it sucks that we can't know what config properties are available or required by a new dependency that we add. For example, if I add one of the Spring Cloud starter packages, I cannot run the application unless I set a bunch of config variables that are required by it... but you can't just look up in some obvious place where all of those newly required things live and what they're supposed to be! You just have to hope that the new package has good enough documentation for you to be able to figure it out.

IntelliJ Idea is able to offer code completion for spring configuration parameters, so there has to be some mechanism that exposes them

Sagacity
May 2, 2003
Hopefully my epitaph will be funnier than my custom title.
It does indeed.

Love Stole the Day
Nov 4, 2012
Please give me free quality professional advice so I can be a baby about it and insult you
This is a good example of that old saying that the fastest way to learn how to do something on the internet is to assert that it's not possible to do, because I posted itt asking about this exact thing like 2 months ago and nobody seemed to know, then I also asked in work chat and everybody said that it isn't possible.


edit-- Actually, using the `spring-boot-starter-security` collection of JARs, it looks like hardly any of them actually contain that metadata.json file in their META-INF folder.

Love Stole the Day fucked around with this message at 21:47 on May 30, 2020

Sagacity
May 2, 2003
Hopefully my epitaph will be funnier than my custom title.
IIRC the starter jars only contain the autoconfiguration classes. You'll probably need to check the underlying Spring Security library JARs (i.e. the transitive dependencies of that starter JAR)

Guildenstern Mother
Mar 31, 2010

Why walk when you can ride?
So I've been working on this pre-bootcamp homework and I've got one assignment left and I just can't get one part to work. Its a change calculator and everything seems to be working fine but the pennies.

code:
public class ChangeCalc {

	public static void main(String[] args) {
		double amntGiven = 18;
		double amntRecieved = 17.18;
				
	makeChange(amntGiven, amntRecieved);			
	}
	private static void
		makeChange( double amntGiven, double amntRecieved) {
		
		double result = amntGiven - amntRecieved;
		System.out.println(result);
		int quart = (int) (result / .25);
		int dime = (int) ((result % .25) /.10);
		int nick = (int) (((result % .25) % .10) / .05);
		int penn =  (int) (((result % .25) % .10) % .05); 
I'm sure there's an easier way to do this, but the lessons have been a bit sparse so far and most of the information I've found on google uses a bunch of things that haven't been covered so I'm hesitant to use anything more complicated than basic operators.

CPColin
Sep 9, 2003

Big ol' smile.
I didn't realize % even worked on doubles. I would have done all the calculations in cents, to avoid floating-point rounding errors, but for the code you have, maybe try dividing by 0.01 at the end of the pennies calculation?

Guildenstern Mother
Mar 31, 2010

Why walk when you can ride?
Somehow that gives me 5 extra pennies. Re: the weird use of % all I can say is that when all you have is a hammer... I had a similar problem earlier and was driving myself nuts trying to find how to get it to give me the remainder, found that operator and have been leaning on it very heavily since. If I were to do it in cents I'd want to set up amntGiven etc to multiply by 100 and then do something similar keeping everything as ints?

Kilson
Jan 16, 2003

I EAT LITTLE CHILDREN FOR BREAKFAST !!11!!1!!!!111!

Guildenstern Mother posted:

So I've been working on this pre-bootcamp homework and I've got one assignment left and I just can't get one part to work. Its a change calculator and everything seems to be working fine but the pennies.

I'm sure there's an easier way to do this, but the lessons have been a bit sparse so far and most of the information I've found on google uses a bunch of things that haven't been covered so I'm hesitant to use anything more complicated than basic operators.

After each coin, why not subtract that amount and just work with the remainder? Then at the end you don't even have to calculate pennies.

code:

double result = amntGiven - amntRecieved;
System.out.println(result);
int quart = (int) (result / .25);
result -= quart * .25;
int dime = (int) (result /.10);

etc.

It makes each step a little simpler, and if you're having trouble it's easier to step through and see if any of your values are wrong.

Guildenstern Mother
Mar 31, 2010

Why walk when you can ride?
That's really helpful actually. I never did end up figuring out how to deal with remainders the long way. Thank you!

lifg
Dec 4, 2000
<this tag left blank>
Muldoon
I have a spring boot application. I’d like one of my REST APIs to return immediately with a 200, while it continues to do some very long computations is the background.

I can do this with threads, and I got it working with Runnable.

But what’s the best practice for this?

M31
Jun 12, 2012

Guildenstern Mother posted:

I'm sure there's an easier way to do this, but the lessons have been a bit sparse so far and most of the information I've found on google uses a bunch of things that haven't been covered so I'm hesitant to use anything more complicated than basic operators.

It's because doubles behave different from the maths that you expect. You can check with jshell:

code:
jshell> 1d % 0.05
$1 ==> 0.04999999999999995
This is why CPColin mentioned using cents (stored as an int or long) because those behave as you would expect. Another option would be BigDecimal (which also has unexpected behavior when it comes to currency amounts, like 1 != 1.00).

I actually last week had a mobile wallet use doubles somewhere and send me $20.0000000001 or something after paying $20.

Kilson
Jan 16, 2003

I EAT LITTLE CHILDREN FOR BREAKFAST !!11!!1!!!!111!

lifg posted:

I have a spring boot application. I’d like one of my REST APIs to return immediately with a 200, while it continues to do some very long computations is the background.

I can do this with threads, and I got it working with Runnable.

But what’s the best practice for this?

Use a thread pool (ExecutorService or something like that - there are several different versions of the class depending on what you need exactly)

That way you can queue the tasks and make sure too many don't run at once, etc.

Pedestrian Xing
Jul 19, 2007

Kilson posted:

Use a thread pool (ExecutorService or something like that - there are several different versions of the class depending on what you need exactly)

That way you can queue the tasks and make sure too many don't run at once, etc.

If you want to go a little farther, you can have the API call trigger a Spring ApplicationEvent, a JMS message, or something like Kafka. The first two are doable purely within Spring and the latter two allow you to scale out more easily.

Volguus
Mar 3, 2009

lifg posted:

I have a spring boot application. I’d like one of my REST APIs to return immediately with a 200, while it continues to do some very long computations is the background.

I can do this with threads, and I got it working with Runnable.

But what’s the best practice for this?

Like others have said, a messaging system (JMS, AMQP) is probably the best way to go for future expansion. But if you really only wanna fire off a long running task, sometimes @Async may do just fine. It is essentially an Executor running tasks in a thread pool, but managed by spring.

Guildenstern Mother
Mar 31, 2010

Why walk when you can ride?
I ended up sending it out without the pennies problem solved. I kind of felt it was against the spirit of the exercise to keep googling the problem asking for help from the internet when I got stuck. I explained my problems and questions in the comments. I for some reason have no problems with the idea of doing this with actual coursework or anything job related.

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

Honestly it's like people said, you'd have been best doing it in cents, that way you're just working with integers - which is what they are really! The decimal point is a trick, you're not working with arbitrary floating point numbers, just a simple whole number that happens to have been divided by 100

You had the right idea (and that divide and mod trick comes up quite a lot, so it's good you're getting used to doing it) - your method was sound, and you might have avoided the repetition yourself if you weren't casting your final values to ints, meaning you couldn't use them in the next double calculation (another sign you should be working with ints anyway, they're what you wanted in the end)

You just got tripped up by getting into the floating point zone, which is a strange and messed up place, and you ran into the accuracy problems. But hopefully now you'll have more of a sense of when to use them and when to avoid them! It's a learning process eh

e- also don't be afraid to post in here if you get stuck, people can give you a general hint without telling you how to solve it, which is definitely better than banging your head against the wall

baka kaba fucked around with this message at 08:59 on Jun 3, 2020

ivantod
Mar 27, 2010

Mahalo, fuckers.

M31 posted:

Another option would be BigDecimal (which also has unexpected behavior when it comes to currency amounts, like 1 != 1.00).

Everybody learns quickly to use compareTo() or stripTrailingZeros() when comparing BigDecimals. The trailing zeros also count when calling getScale(), so you better remember to do stripTrailingZeros() also there if you want to check e.g. that the scale is correct against the currency that you're using or stuff like that.

But to add to the pile for the original question, definitely never use double/float for money amounts, because that just doesn't work. Either integers and work in cents or arbitrary precistion decimal numbers like BigDecimal.

lifg
Dec 4, 2000
<this tag left blank>
Muldoon
Thanks, all. I’ll read up on those.

smackfu
Jun 7, 2004

This is nonsense, right?
code:
Optional.ofNullable(value.trim()).orElse(null)
What were they even thinking?

Pedestrian Xing
Jul 19, 2007

smackfu posted:

This is nonsense, right?
code:
Optional.ofNullable(value.trim()).orElse(null)
What were they even thinking?

Yes, it will either return a trimmed string or throw an NPE. I assume they meant to do this:
code:
Optional.ofNullable(value).map(String::trim).orElse(null);
which is functionally identical to this:
code:
return value != null ? value.trim() : null;
but involves an extra object allocation.

Adbot
ADBOT LOVES YOU

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

Kind of a weird request, but does anyone know of any substantial Java EE projects on Github? Ideally it would have some decent Java EE usage but any larger .war/.ear could at least be helpful. The largest I've found so far is Jenkins which offers a .war but that doesn't have much interesting in it as far as the tool I want to run against it is concerned.

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