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
Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
Yes, it's a configuration issue. I had this thing running on Tomcat and managed to get DEBUG (and TRACE) level logging working there, but now on jetty I'm back to only having INFO and up.

Not that it matters anymore, I just search-replaced all my debug calls with info calls and then reverted those changes before committing my work back to git.

Adbot
ADBOT LOVES YOU

casual poster
Jun 29, 2009

So casual.
Whoa, just found out about the Generate menu in Netbeans, pretty drat cool time saver

Nude
Nov 16, 2014

I have no idea what I'm doing.
Hey again, so I have been reading up on Java's pass by value. And just want to confirm if I fully understand what's happening. Specifically I'm talking about this:

Java code:
class Human {
	public String Name;
}

public class Main {
	public static void main (String[] args) {
	Human bob = new Human();
	bob.Name = "Bob";
	
	changeNameToSherlock(bob.Name);
	System.out.printf(bob.Name); //Outputs Bob.
	
	changeNameToSherlock(bob); 
	System.out.printf(bob.Name); //Outputs Sherlock.
	}

	//Methods
	public static void changeNameToSherlock (String name) {
	name = "Sherlock";
	}

	public static void changeNameToSherlock (Human human) {
	human.Name = "Sherlock";
	}
}
The way I understand it is this: when you pass an object through a parameter the reason why it can be modify is because the parameter's object is not created until you pass it, so both objects have the same address. When you pass a variable through a parameter both the parameter's variable and the variable being passed are created separately so that's why they don't have the same address. Is this a correct understanding of the way Java handles data?

Nude fucked around with this message at 02:06 on Apr 26, 2016

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
In Java, with the exception of a small handful of types, everything you interact with is actually a pointer that points to a specific object in memory.

Method parameters are always passed by value. For most types, when you pass it as a parameter, the called function receives a copy of the pointer that points to the same piece of memory.

So, if you reassign a method parameter to point to somewhere different, that has no effect outside of the method - you're only changing the method's local copy of the pointer. But if you make a change to the actual object being pointed to, that will be visible outside of the method, because all the pointers refer to the same object in memory.

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

Or to put the same thing another way, if you're not familiar with pointers - when you do something like this
Java code:
Human bob = new Human();
you're doing two things - on the left side you're creating a reference to a Human object, and you're calling that reference 'bob'. On the right side you're actually creating a Human object, and then the = points your bob reference at it.

So when you have a method like
Java code:
public static void changeNameToSherlock (Human human) {
    human.Name = "Sherlock";
}
that's creating another, local reference to a Human object inside the method, and you're calling that reference 'human'. That needs to be pointed at something, so when you call it with
Java code:
changeNameToSherlock(bob);
you're pointing the 'human' label at the same object that 'bob' is pointing at. The important thing is that the 'bob' and 'human' labels are separate, they just happen to be pointing at the same thing right now. Your method can change what 'human' points at (say by going human = new Human()), but it can't change what 'bob' points at. It can mess with the internals of the object they're both referencing, like when you change its name, but that's all.

It's called pass by value because when you call changeNameToSherlock(bob), you're passing in whatever the value of 'bob' is, not the actual 'bob' reference itself. So you can't change what 'bob' is looking at, reassigning it to another object or whatever - but if you can mutate the thing that 'bob' is looking at, 'bob' will see those changes because it's looking at the same object

Same thing is happening when you pass in bob.name - you're taking the name reference inside that object, and passing its value to a method. And that value is a String, and those are immutable in Java, so you can't change what bob.name sees either.

Nude
Nov 16, 2014

I have no idea what I'm doing.

Jabor posted:

In Java, with the exception of a small handful of types, everything you interact with is actually a pointer that points to a specific object in memory.

Method parameters are always passed by value. For most types, when you pass it as a parameter, the called function receives a copy of the pointer that points to the same piece of memory.

So, if you reassign a method parameter to point to somewhere different, that has no effect outside of the method - you're only changing the method's local copy of the pointer. But if you make a change to the actual object being pointed to, that will be visible outside of the method, because all the pointers refer to the same object in memory.


baka kaba posted:

A really good effort post.

Okay I'm gonna need seem time to digest these, as my brain goes from understanding to :psyduck:. I'll throw out one last thing on what I took away from this, and if it's still off I suppose I'll have to start reading more in depth about it. I should read more about this stuff anyway as it's kind of fascinating to me. First thing I learned is some objects are immutable and some mutable (two key terms that I didn't really know until I looked them up). This seems to play a big role on how they're used/passed. Now what this suggests to me is that:

Java code:
String immutable = "hi"; //Original reference
immutable = "foo"; //the reference is changed
immutable = new String("bar"); //the reference is changed again

Human mutable = new Human(); //Original reference
mutable.Name = "Bob"; //mutable is still at the original reference, while mutable.Name's reference has changed.
mutable = new Human(); //mutable's reference has now changed

So lastly when I do 
public static void changeNameToSherlock (String name) {
    name = "Sherlock"; //creates a new reference to name thus disconnecting it from whatever is passed. 
}

//*************BUT***********//

public static String sameReference (String name) {
	return name;
}

bob.Name == sameReference(bob.Name); //This is true because both name and bob.Name point to the same object. 
Hopefully that's on the right track. And if it is I think I just need to let it sit for a bit and sink in. Either way thanks for the help.

Nude fucked around with this message at 06:47 on Apr 26, 2016

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.
Whats key in cases like this is that while if you pass an object, say a Human named bob, and then assign that pointer to something else, you haven't modified the original object, BUT you can modify the state of the object, including other objects it has references to, and those will cause changes to other references because you're still referring to the same object.

A key example is a List. You can pass a List like

public void doStuff (List inventory){
//does stuff to inventory
}

If you were to then set

inventory = new Arraylist();

That would only modify the local reference, not other references to that object. They'd still point to the original object, and you'd just lose your reference to it.
However, if you do something like

inventory.add(Bob);

Then all other references to that List would see the change, with the new Bob object in the list, because you haven't changed the reference, you've modified the internal state of the object. (Its just in this case, a List, the internal state itself can be references to other objects)
You could also do things like

inventory.remove(Bob);

And other references would see that the List inventory had its internal reference to Bob removed.
Clear as mud?

Nude posted:

code:
So lastly when I do 
public static void changeNameToSherlock (String name) {
    name = "Sherlock"; //creates a new reference to name thus disconnecting it from whatever is passed. 
}

//*************BUT***********//

public static String sameReference (String name) {
	return name;
}

bob.Name == sameReference(bob.Name); //This is true because both name and bob.Name point to the same object. 
Hopefully that's on the right track. And if it is I think I just need to let it sit for a bit and sink in. Either way thanks for the help.

Yep yep

Zaphod42 fucked around with this message at 06:59 on Apr 26, 2016

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

Zaphod42 posted:

However, if you do something like

inventory.add(Bob);

Then all other references to that List would see the change, with the new Bob object in the list, because you haven't changed the reference, you've modified the internal state of the object. (Its just in this case, a List, the internal state itself can be references to other objects)
You could also do things like

inventory.remove(Bob);

And other references would see that the List inventory had its internal reference to Bob removed.

I want to expand on this part a bit more because it's where everything you're studying starts to become relevant, interesting, and really loving hard :q: See what the JavaDoc for ArrayList has to say about modifying a list while other threads have a reference to it.

quote:

Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the list. If no such object exists, the list should be "wrapped" using the Collections.synchronizedList method. This is best done at creation time, to prevent accidental unsynchronized access to the list:

List list = Collections.synchronizedList(new ArrayList(...));

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

What this means is that if one thread is iterating over the list and another thread calls add or remove then the first thread will throw that ConcurrentModificationException.

Janitor Prime fucked around with this message at 19:41 on Apr 26, 2016

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

Nude posted:

Okay I'm gonna need seem time to digest these, as my brain goes from understanding to :psyduck:. I'll throw out one last thing on what I took away from this, and if it's still off I suppose I'll have to start reading more in depth about it. I should read more about this stuff anyway as it's kind of fascinating to me.

It's actually pretty simple conceptually, so if we're confusing you then let me try and hamfist an analogy here

Imagine there's a warehouse with all these spaces for boxes. Rows and rows of shelves, with each spot labelled with a specific code so you can specify and find that spot. Some of the spaces are empty, some of them have boxes in them.

When you create a new object, it's filed away in the warehouse, and you get a location code back. If you want to interact with the object, you need to go to that location. So you'll probably want to write that location code down, along with a name you can refer to it by. Imagine you have a whiteboard with a list of names and their associated locations

If you need someone else to do something with that object, you can give them the location code. That way they can access the same object, by going to the same location. They have their own whiteboard to write the code down along with a name - they can call it whatever they want on their own board, like "IMPORTANT_THING". Maybe later they're done with your object, and they change IMPORTANT_THING on their whiteboard to refer to a different location, some other spot in the warehouse. That won't affect your whiteboard - you'll still have the same name, and the same location code. They can't affect your reference, only you can change that.

What they can do it go along to the location in the warehouse, and mess with the object at that location. This is where mutability comes in - if things inside the object can be changed, you'll see those changes when you go to that location yourself. You're both looking at the same object, because you both have independent references to the same location.

Now imagine the object at that spot (call it Spot A) contains its own objects. They're not actually inside it, it's more like it contains its own whiteboard with names and location codes - the 'contained' objects are actually in different spots in the warehouse. The important thing here is that you and the other guy both have access to the same whiteboard, because it's inside the object you're both looking at. So in this situation, you can change a reference (say pointing "Name" from Spot B to Spot C), and everyone with access to the object will see that change, because they're looking at the same whiteboard. But if anyone anywhere has their own separate whiteboard reference to Spot B, that won't be changed

So in Java, when you're working with objects, you're only passing around their location codes, not the whiteboard itself (which would be passing a reference). It's a subtle difference, but it means a method can only affect an object it's passed, it can't make other things that are looking at that object point to something else. If you want to do something like that (if you have several things that all need to be looking at the same object, with the ability to change where they're all looking) you need to stick the reference in an object and pass that around. That's all your Human.name field is, in the end - a reference to a String, and anything with access to that object can point it at a different String

That's a lot of words for a basic concept I'm probably making it worse :ohdear:

Carbon dioxide
Oct 9, 2012

Nude posted:

Java code:

public static String sameReference (String name) {
	return name;
}

bob.Name == sameReference(bob.Name); //This is true because both name and bob.Name point to the same object. 
Hopefully that's on the right track. And if it is I think I just need to let it sit for a bit and sink in. Either way thanks for the help.

This is correct, and you picked up on another interesting thing here. To help you understand it, I'll introduce a few more terms. Within the Java Virtual Machine's memory, there are two parts, the stack and the heap. How those are internally organized is not important right now. What is, is the way Java deals with them. Look at these examples:

Java code:
int x; // Creates an integer primitive with a default value (which is 0) on the stack.
Integer y; // Creates an object pointer on the stack. This pointer doesn't point at anything yet, it's a null pointer
y = new Integer(3); // Points y to an Integer object containing the value 3. This object is created on the heap.
Edit: the poster above me used metaphors. In that metaphor, the whiteboards are the stack, while the warehouse is the heap.

So, in short, primitives (boolean, byte, short, int, long, float, double, char) are created on the stack and directly contain some number or a character. If you pass a primitive on to a method, it just passes the value, and the method doesn't know where the original primitive was located on the stack.

Objects, such as Integer, are created on the heap and accessible by a pointer on the stack. When you pass an object to a method, it actually passes on the pointer and both the method and the place where it was called are now talking to the same object. Much of Object Orientied Programming is about passing on pointers to methods in the correct way and thinking about what effects that'll have. At my job, we often use Integer instead of int, because Integer can be a null pointer, and being able to tell your methods that a variable has not yet been assigned is often useful.

In any case, this difference between objects and primitives leads to an interesting quirk:
Java code:
int a = 3;
int b = 3;
a == b; // true

Integer c = new Integer(3); 
Integer d = 3; // This is equivalent to Integer d = new Integer(3);
               // it's a trick you can do with the objects that belong with primitive types called 'autoboxing'
c == d; // false
c.equals(d); // true

String foo = "string";
String bar = "string";
bar == foo; // I have no idea whether this will return true or false
bar.equals(foo); // true
Basically, the == compares whatever is stored on the stack. In other words, it compares references. In case of primitives, it's fine to check whether two values are equal. Both a and b have the value '3' on the stack, so it will return true.

In case of objects, such as Integer, == will compare the pointers on the stack. c and d point to different Integer objects, so this will return false. To test for equality, you basically have to check all relevant fields within an object one by one. This is what the equals() method in common JDK objects does, and when you want to compare objects you made yourself, you'll have to implement the equals() method in them. In your example, the == will return true because you are indeed comparing two references that point to the same object on the heap.

So, basically, for primitives you want to always use ==, for objects you want to use equals() unless you have a very good reason to compare references. You do use x == null to check whether an object reference is actually a null pointer, an unassigned object. In that case equals() won't work because there's no actual reference yet to any object with an equals() method.

Finally, there's the weird case with Strings. Strings are immutable objects and are strongly optimized by Java. Because they cannot change anyway, sometimes Java will take a shortcut to save some memory, and have foo and bar point to the same String object. If that happens, == will return true, otherwise it will be false. This actually depends on the current state of the program, and it's hard to predict what will happen, especially if that method can be called in different situations. So, while string1 == string2 may return true in some cases, it's not a safe way to check String equality, and you should always use string.equals() for that.

Carbon dioxide fucked around with this message at 19:44 on Apr 26, 2016

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.
I'm worried you guys may be getting ahead of yourselves, when he/she's working out how pass-by-reference works we don't really need to start inserting thread safety or stack vs heap into the conversation right away. Its good stuff but can be very overwhelming and even confusing if you're still trying to nail down the references in the first place.

I know, I do it too sometimes :cheeky:

Baka kaba's post is just a nice metaphor explaining the concept asked about.

code:
bar == foo; // I have no idea whether this will return true or false
I doubt that the compiler would recognize that the string literals were the same and point them to the same object, even if that shouldn't really cause any problems because strings are immutable. So I would figure false if this was asked of me in an interview or something, but its worth testing. You never know what voodoo they snuck into the compiler, poo poo's smart.

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

Zaphod42 posted:

code:
bar == foo; // I have no idea whether this will return true or false
I doubt that the compiler would recognize that the string literals were the same and point them to the same object, even if that shouldn't really cause any problems because strings are immutable. So I would figure false if this was asked of me in an interview or something, but its worth testing. You never know what voodoo they snuck into the compiler, poo poo's smart.

It's called String interning

quote:

The JVM performs some trickery while instantiating string literals to increase performance and decrease memory overhead. To cut down the number of String objects created in the JVM, the String class keeps a pool of strings. Each time your code declares a string literal, the JVM checks the string literal pool first. If the string already exists in the pool, a reference to the pooled instance returns. If the string does not exist in the pool, a new String object instantiates, then is placed in the pool.
How big the pool is varies by JVM/platform but it's something it already does.

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

Carbon dioxide posted:


In any case, this difference between objects and primitives leads to an interesting quirk:
Java code:
Integer d = 3; // This is equivalent to Integer d = new Integer(3);

#JustJavaThings, but this isn't true right? As far as I remember (phoneposting when I shouldn't be) there's a pool of Integer objects for a certain range of values, and when you do Integer d = 3 it assigns d to the pre-existing object instead of creating a new one. You have to explicitly create a new Integer object if that's what you want. So

Java code:

Integer a = 3;
Integer b = 3;
Integer c = new Integer(3);

a == b
a != c

It's more of an issue with Strings, but the general rule is if you want to compare objects by value, use equals() to avoid weird edge case bugs

CPColin
Sep 9, 2003

Big ol' smile.

baka kaba posted:

#JustJavaThings, but this isn't true right? As far as I remember (phoneposting when I shouldn't be) there's a pool of Integer objects for a certain range of values, and when you do Integer d = 3 it assigns d to the pre-existing object instead of creating a new one. You have to explicitly create a new Integer object if that's what you want. So

I just checked the bytecode that line generates and you're right. The autoboxing makes it Integer d = Integer.valueOf(3), which does check a cache for values between -128 and a system property that defaults to 127. I didn't know that, but that's okay; I should never care exactly which Integer instances I'm dealing with.

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, it's more that == behaves 'differently' depending on how you got your Integer objects, or what values you autoboxed. Ideally you'd never put yourself in a situation where it would trip you up, but it's still a gotcha that could be real confusing if you had no idea it was even a thing

Nude
Nov 16, 2014

I have no idea what I'm doing.
I was tinkering around was just about to ask how come:

code:
string foo = "one";
string bar = "one";
foo == bar //returned true!
But you guys already answered that ha ha.

Carbon dioxide posted:

This is correct, and you picked up on another interesting thing here. To help you understand it, I'll introduce a few more terms. Within the Java Virtual Machine's memory, there are two parts, the stack and the heap. How those are internally organized is not important right now. What is, is the way Java deals with them. Look at these examples:

In case of objects, such as Integer, == will compare the pointers on the stack. c and d point to different Integer objects, so this will return false. To test for equality, you basically have to check all relevant fields within an object one by one. This is what the equals() method in common JDK objects does, and when you want to compare objects you made yourself, you'll have to implement the equals() method in them. In your example, the == will return true because you are indeed comparing two references that point to the same object on the heap.

Finally, there's the weird case with Strings. Strings are immutable objects and are strongly optimized by Java. Because they cannot change anyway, sometimes Java will take a shortcut to save some memory, and have foo and bar point to the same String object. If that happens, == will return true, otherwise it will be false. This actually depends on the current state of the program, and it's hard to predict what will happen, especially if that method can be called in different situations. So, while string1 == string2 may return true in some cases, it's not a safe way to check String equality, and you should always use string.equals() for that.

Janitor Prime posted:

It's called String interning

How big the pool is varies by JVM/platform but it's something it already does.

This clears that up, had a mini hard attack thinking I was still not getting it ha ha. That Integer vs int stuff that Carbon Dioxide posted is really interesting. I want to thank you guys for the effort posts and analogies extremely useful for grasping this concept.

Nude fucked around with this message at 03:39 on Apr 27, 2016

22 Eargesplitten
Oct 10, 2010



I'm testing a game based out of a JFrame. I'm testing the results of methods that happen when you hit a button with JUnit. An example method definition is something like this:

code:
public void appeaseActionPerformed( java.awt.event.ActionEvent evt) 
What would I feed in as an argument from within a JUnit test?

CPColin
Sep 9, 2003

Big ol' smile.
I'd probably debug that method and see what gets passed in when you click the button normally, then create an instance of ActionEvent in your test that matches that. I don't know if that counts as valid testing, or what.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

CPColin posted:

I'd probably debug that method and see what gets passed in when you click the button normally, then create an instance of ActionEvent in your test that matches that. I don't know if that counts as valid testing, or what.

Well, on a TDD course I took, this is exactly what the instructor did, with a more trivial example:

Java code:
public int sum (int a, int b) {
	return a + b;
}
"I don't loving know what 1 + 2 is supposed to be, so I'll just guess. IDK, a million":
Java code:
// test code
assertEquals(1000000, sum(1, 2));
"Whoops, that didn't work, apparently it's 3"
Java code:
// test code
assertEquals(3, sum(1, 2));
"That turned the test green, let's move on"

Kilson
Jan 16, 2003

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

Wheany posted:

Well, on a TDD course I took, this is exactly what the instructor did, with a more trivial example:

Java code:
public int sum (int a, int b) {
	return a + b;
}
"I don't loving know what 1 + 2 is supposed to be, so I'll just guess. IDK, a million":
Java code:
// test code
assertEquals(1000000, sum(1, 2));
"Whoops, that didn't work, apparently it's 3"
Java code:
// test code
assertEquals(3, sum(1, 2));
"That turned the test green, let's move on"

This sort of bothers me. What if the sum method was incorrect? Then you're just asserting wrong results and your test is worthless. In a nontrivial case you can't just do that.

I know it doesn't stop people though. I've seen plenty of tests that just assert that the method does what it says it does, tautologically, rather than what it's *supposed* to do.

speng31b
May 8, 2010

In a perfect world maybe tests would be great at making things do what they should do in some grander principled sense, but really what they're supposed to do is make sure things keep doing what the programmer originally expected them to. If you think tests primarily exist to make things work how they "should" you're wrong about tests. They just make sure things keep working how they do, and if not, you know about it sooner rather than later.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Kilson posted:

This sort of bothers me. What if the sum method was incorrect? Then you're just asserting wrong results and your test is worthless. In a nontrivial case you can't just do that.

Unit tests help you make sure that your changes do not change the behavior of existing code.

If a test breaks, then your behavior has changed. If that was because you fixed a bug, then you need to fix the test. If it was because your new code caused some side effect you were unaware of, well now you're aware.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
"Refactoring" has a very specific meaning that I just learned a couple of years ago. I used to think that it's just "do whatever (to make the code better?) and try not to break poo poo"

Actually it means that "Whatever changes you do, don't loving change the behavior" and making sure you don't change things requires you to have good unit test coverage. Refactoring and fixing bugs are two different things, and if you find a bug while refactoring, you're supposed to leave it it until you start debugging.

This also means that you might have to do a lot of "best effort" changes that might break something while you don't have testable code, to make the code testable (and add tests).

TheresaJayne
Jul 1, 2011

Wheany posted:

Unit tests help you make sure that your changes do not change the behavior of existing code.

If a test breaks, then your behavior has changed. If that was because you fixed a bug, then you need to fix the test. If it was because your new code caused some side effect you were unaware of, well now you're aware.

Of course if you are fixing a bug you should first write a test for the bug that fails until the bug is fixed. then you know when you have fixed it and you can always confirm there has been no regression

smackfu
Jun 7, 2004

Wheany posted:

Well, on a TDD course I took, this is exactly what the instructor did, with a more trivial example:

...

"Whoops, that didn't work, apparently it's 3"
Java code:
// test code
assertEquals(3, sum(1, 2));
"That turned the test green, let's move on"

Um, isn't this a bit backwards if you are calling it TDD? You are supposed to change the code to make the test green, not the test. So the test should always say 3 (when you write it first), but the sum() method might have originally just returned the constant 3 instead of a+b.

smackfu fucked around with this message at 11:55 on Apr 27, 2016

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

smackfu posted:

Um, isn't this a bit backwards if you are calling it TDD? You are supposed to change the code to make the test green, not the test. So the test should always say 3 (when you write it first), but the sum() method might have originally just returned the constant 3 instead of a+b.

It might have been that, or maybe the teacher was bad. I don't know, all I remember is that the process involved "lol idk, let's just see what the result is"

weas
Jul 22, 2007

Tougher than the
toughest tough guy
Yeah the teacher was bad lmao. TDD means you write valid tests before you write a single line of implementation code.

Kilson
Jan 16, 2003

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

Wheany posted:

Unit tests help you make sure that your changes do not change the behavior of existing code.

If a test breaks, then your behavior has changed. If that was because you fixed a bug, then you need to fix the test. If it was because your new code caused some side effect you were unaware of, well now you're aware.

I understand the general point of tests, and the workflow involved in adding/changing them. I don't understand why asserting wrong behavior through tests is particularly useful.

Also what smackfu said.

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

Janitor Prime posted:

It's called String interning

How big the pool is varies by JVM/platform but it's something it already does.

Wow, and its specifically for strings? Well, that's exactly the kind of compiler voodoo I was talking about. Cool.

CPColin posted:

I just checked the bytecode that line generates and you're right. The autoboxing makes it Integer d = Integer.valueOf(3), which does check a cache for values between -128 and a system property that defaults to 127. I didn't know that, but that's okay; I should never care exactly which Integer instances I'm dealing with.

Yeah it should be irrelevant which is why they do it, but that's good to know.

speng31b posted:

In a perfect world maybe tests would be great at making things do what they should do in some grander principled sense, but really what they're supposed to do is make sure things keep doing what the programmer originally expected them to. If you think tests primarily exist to make things work how they "should" you're wrong about tests. They just make sure things keep working how they do, and if not, you know about it sooner rather than later.

Well, there's unit testing and there's integration testing. Integration testing is definitely about making sure that things keep working as expected when plugged together, and unit tests can be used as regressions testing as well, but you can also use unit testing to verify the original requirements too. TDD is all about that. Making sure things keep working as they did doesn't make sense when you're writing tests before you even started writing code. That's for verifying requirements.

smackfu posted:

Um, isn't this a bit backwards if you are calling it TDD? You are supposed to change the code to make the test green, not the test. So the test should always say 3 (when you write it first), but the sum() method might have originally just returned the constant 3 instead of a+b.

Yepyep.

Zaphod42 fucked around with this message at 15:25 on Apr 27, 2016

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
I loving knew mentioning tdd was a terrible idea

Sedro
Dec 31, 2008

Wheany posted:

I loving knew mentioning tdd was a terrible idea

22 Eargesplitten
Oct 10, 2010



CPColin posted:

I'd probably debug that method and see what gets passed in when you click the button normally, then create an instance of ActionEvent in your test that matches that. I don't know if that counts as valid testing, or what.

This is what I'm getting from a different button press:

This is where the function is defined.

code:
    ImpBarr.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        impBarrActionPerformed(evt);
      }
    });
This is the object data for evt in the debug menu.

code:
evt	ActionEvent  (id=76)	
	acc	AccessControlContext  (id=86)	
	actionCommand	"Improve Barricades" (id=88)	
	bdata	null	
	consumed	true	
	focusManagerIsDispatching	false	
	id	1001	
	isPosted	false	
	isSystemGenerated	false	
	modifiers	16	
	source	JButton  (id=80)	
	when	1461782180052	
Is there a way to create an action event with all those parameters? I've never had to do anything like this. In school, almost all of my projects were terminal-based.

CPColin
Sep 9, 2003

Big ol' smile.
Most of that stuff is internal stuff you can't set. You can call the ActionEvent constructor:

code:
new ActionEvent(theButtonThatWasClicked, ActionEvent.ACTION_PERFORMED, "Improve Barricades");
If that impBarrActionPerformed() method doesn't call evt.getSource() or evt.getCommand(), you can probably pass nulls for those parameters. If the method doesn't check anything in the event at all, you can probably skip creating an event altogether.

But, at that point, you're not really testing much.

Adventure Pigeon
Nov 8, 2005

I am a master storyteller.
So I'm feeling a bit overwhelmed by the task before me.

I took up Java a few years back after working in Perl for years. I'm a biologist who started programming because of the size of the datasets I was working with and because existing tools didn't always do what I wanted them to. I've gotten reasonably far googling and just working my way through problems, but more and more I'm starting to feel limited. I'm purchasing a few recommended books to try to fix this.

Anyways, my client has requested I set up a data sharing system. Basically, they want to be able to remotely access and search datasets I've generated. I can do a reasonable amount of database programming. I have a sample tracking app I made that interfaces with a mySQL server through JDBC. It's not too complex, but that part of the problem I at least have an understanding of.

The part I'm having trouble with, and this is something I've avoided doing for a while, is actually doing client-server stuff. I want to build a simple interface app that will allow the client to contact my server and request data off of it, but I have no idea where to start. There're a lot of frameworks and a lot of information out there for how to implement a system, and it's a bit overwhelming. Where's a good starting point for building an app like this? Is there a recommended framework to start working with? Down the road I may need to think about creating a dynamic web page for clients to access information, so it might be time for me to start looking into building an actual webserver.

Basically, what's the best way to get started on these problems?

Volguus
Mar 3, 2009

Adventure Pigeon posted:

So I'm feeling a bit overwhelmed by the task before me.

I took up Java a few years back after working in Perl for years. I'm a biologist who started programming because of the size of the datasets I was working with and because existing tools didn't always do what I wanted them to. I've gotten reasonably far googling and just working my way through problems, but more and more I'm starting to feel limited. I'm purchasing a few recommended books to try to fix this.

Anyways, my client has requested I set up a data sharing system. Basically, they want to be able to remotely access and search datasets I've generated. I can do a reasonable amount of database programming. I have a sample tracking app I made that interfaces with a mySQL server through JDBC. It's not too complex, but that part of the problem I at least have an understanding of.

The part I'm having trouble with, and this is something I've avoided doing for a while, is actually doing client-server stuff. I want to build a simple interface app that will allow the client to contact my server and request data off of it, but I have no idea where to start. There're a lot of frameworks and a lot of information out there for how to implement a system, and it's a bit overwhelming. Where's a good starting point for building an app like this? Is there a recommended framework to start working with? Down the road I may need to think about creating a dynamic web page for clients to access information, so it might be time for me to start looking into building an actual webserver.

Basically, what's the best way to get started on these problems?

I would stay away from a desktop application, for the simple reason that the easiest way for the application to connect to the database would be to simply make the database available on the network. It doesn't matter what database you use, how good your password is, how up to date are you with the patches, a database exposed on the network (internet ... even worse) is a ticking bomb. The question is "when will that data end up all over the internet?" not if.

Therefore, my recommendation would be to start with a web application from the get-go. That would allow to (at least) protect the database somewhat. The web application servers are not the pinnacle of security either, but at least some of them are trying. And, to top it off, a web UI should be relatively easier to implement than a desktop app (depending on your skillset of course).

But, honestly, at this stage it would be a great idea to just hire a developer (as experienced as you can afford), since it sounds like you're spending a fair bit of time on things that you'd rather not spend time on.

Adventure Pigeon
Nov 8, 2005

I am a master storyteller.

Volguus posted:

I would stay away from a desktop application, for the simple reason that the easiest way for the application to connect to the database would be to simply make the database available on the network. It doesn't matter what database you use, how good your password is, how up to date are you with the patches, a database exposed on the network (internet ... even worse) is a ticking bomb. The question is "when will that data end up all over the internet?" not if.

Therefore, my recommendation would be to start with a web application from the get-go. That would allow to (at least) protect the database somewhat. The web application servers are not the pinnacle of security either, but at least some of them are trying. And, to top it off, a web UI should be relatively easier to implement than a desktop app (depending on your skillset of course).

But, honestly, at this stage it would be a great idea to just hire a developer (as experienced as you can afford), since it sounds like you're spending a fair bit of time on things that you'd rather not spend time on.

Thanks for the advice. I'd be fine with starting with a webserver.

Honestly, I don't have an issue spending time on this. This isn't a time sensitive project, it's more along the lines of "Something that'd be nice to have", and for me, it represents a chance to improve my skillset. I'd like to give it a serious shot before I hire a developer, especially if there's a chance I might have to modify it later on.

If it becomes a time sensitive project or if the data becomes something that has to be protected, I'll look into hiring someone, but for now I want to give it my best shot on my own. The data is nothing sensitive or proprietary, so it ending up on the internet wouldn't be the end of the world either. I'd rather start learning now than when it is something highly proprietary.

Elias_Maluco
Aug 23, 2007
I need to sleep

Adventure Pigeon posted:

Thanks for the advice. I'd be fine with starting with a webserver.

Honestly, I don't have an issue spending time on this. This isn't a time sensitive project, it's more along the lines of "Something that'd be nice to have", and for me, it represents a chance to improve my skillset. I'd like to give it a serious shot before I hire a developer, especially if there's a chance I might have to modify it later on.

If it becomes a time sensitive project or if the data becomes something that has to be protected, I'll look into hiring someone, but for now I want to give it my best shot on my own. The data is nothing sensitive or proprietary, so it ending up on the internet wouldn't be the end of the world either. I'd rather start learning now than when it is something highly proprietary.

Yeah, make it a web application.

If you dont want to waste too much time with the UI part of it, use bootstrap:
http://getbootstrap.com/components/

Gives you a lot of elegant effective UI elements right out of the box.

I would recommend using a framework for the server side stuff too., though I cant recommend you one if you mean to do it in java, as I never did any server side java. If you willing to try other languages, you might start with Django (Python) or Symfony (PHP)

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe
I recommend you use Spring Boot since that will get you a built in web server that will be easier to maintain than trying to setup it all up from scratch. Also you can use as much or as little of the Spring framework to glue together your bootstrap frontend and the database backend as you feel comfortable with.

tazjin
Jul 24, 2015


Janitor Prime posted:

I recommend you use Spring Boot since that will get you a built in web server that will be easier to maintain than trying to setup it all up from scratch. Also you can use as much or as little of the Spring framework to glue together your bootstrap frontend and the database backend as you feel comfortable with.

Looking at simpler web "microframeworks" like Spark (have used this in production) or Rapidoid could also be an option. They use modern Java features and are very easy to use with little-to-no boilerplate.

Spring is usually not a tech stack that makes people happy in the long run, especially if they just want to get something simple up and running.

Adbot
ADBOT LOVES YOU

Adventure Pigeon
Nov 8, 2005

I am a master storyteller.
I'll give this a look, thanks for the advice.

I was also wondering, given your statements about how allowing direct access to the database on the network, much less the web, is a bad idea, what is the best way to set up my database?

I was already planning on having a system along the lines of Client <----> Server <----> Database, since I don't want anyone directly accessing the database, but I don't know all that much in terms of how to physically set that up.

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