Live data from Hacker News

Breaking java.lang.String

wouter.coekaerts.be

51–60 of 206 posts

Re: Breaking java.lang.String

#51
post #6
post #4

Earlier quoted context omitted.

Mutexes etc ... exist in Java.

Right, but in rust, not using one is a compile time error. In Java (as you can see by the article), not using one is a silent bug at runtime.

Only for in-memory data structures under Rust's control, if it is related to OS IPC, Rust cannot do anything.

Re: Breaking java.lang.String

#52
post #4

Earlier quoted context omitted.

Mutexes etc ... exist in Java.

Yes, but Java will happily accept code that doesn't use them where it needs to, leading to bugs like this one. Rust catches that mistake at compile time instead.

Not if the memory has been allocated on a shared memory segment, Rust has no control over what other processes might do.

Re: Breaking java.lang.String

#53

Out of interest, how should this be handled? Is this a bug in Java which should be fixed (looks like that to me)? My understanding was Java generally doesn't do "you did an undefined behaviour, so it's your fault", except for specifically marked very low-level interfaces.

If I would design JVM from the scratch, I'd introduce frozen arrays. There are so many array copies inside JDK code, it hurts.

Whether it's possible to retrofit JVM today, I don't know.

Re: Breaking java.lang.String

#54
post #48

Earlier quoted context omitted.

As the article points out, the only thing the Javadoc guarantees is the subsequent modifications of the character array have no effect. It says nothing about concurrent modifications. The type whose thread safety is in question here is not actually String, but char[]. I'm not going to say it is always wrong to share char[] between threads (as a primitive array of something other than double and long, the Java Spec do…

"The type whose thread safety is in question here is not actually String, but char[]" Not quite, it is String constructor that has the race condition, char array is incidental there.

I wouldn’t point the finger at the ctor; making a defensive deep copy of mutable parameters is not in the contract.

Re: Breaking java.lang.String

#55
post #20

Is this actually a bug? The default assumption in Java is that types are not thread-safe unless otherwise specified. Attempting to use types in a way that exceeds their documented thread safety has always been allowed to leave your program in an inconsistent state.

That's true, but in the case of Strings in particular they are generally considered to be thread-safe by virtue of being immutable (and the Javadocs themselves say this in many places). Concurrently modifying the input character array may seem like willful abuse in this case, but I suppose there might be some carelessly written code out there which does it and the post shows how it would create some weird and very ha…

Immutable types are only considered thread-safe after their construction, though.

Re: Breaking java.lang.String

#56
post #20

Is this actually a bug? The default assumption in Java is that types are not thread-safe unless otherwise specified. Attempting to use types in a way that exceeds their documented thread safety has always been allowed to leave your program in an inconsistent state.

That's true, but in the case of Strings in particular they are generally considered to be thread-safe by virtue of being immutable (and the Javadocs themselves say this in many places). Concurrently modifying the input character array may seem like willful abuse in this case, but I suppose there might be some carelessly written code out there which does it and the post shows how it would create some weird and very ha…

I’d argue that while a string is thread safe, this is not actually a string yet.

Re: Breaking java.lang.String

#57

Calling this a "bug in java.lang.String" is silly. The same "bug" exists for all functions that take mutable objects. If you take a map and lookup two different keys, yep, that's a "bug". The bug is the other piece of code that introduces the data race in the first place. You can argue the case for languages like Rust with it's borrow system, or others that use linear types or something along those lines, to eliminat…

It is probably a gotcha. But yeah if you hit this problem you have bigger worries, the code immediately before the constructor is not thread safe.

Re: Breaking java.lang.String

#58
post #46

Earlier quoted context omitted.

No idea why Thaxll and the other comments are mentioning mutexes. The equivalent (*) API to this Java API in Rust does exist; it's `String::from_utf8(Vec ) -> String`. And the bug in TFA does not exist there. Since the signature consumes the `Vec ` it's impossible for the caller or any other code to still have access to it to be able to modify it concurrently. Also consider the similar API `str::from_utf8(&[u8]) -> &…

The scenario I was imagining and commenting on was about “implementing a JVM with Java’s semantics in Rust”. Of course if we limit the language itself to safe Rust, we get data race freedom, but at a quite significant price for a high level language (it constraints possibly correct programs down a lot ). But Rust would not help with relation to the primitives here at all (implemented in C++/Java).

"Rust wouldn't help"

"This bug can't be implemented in rust"

"I meant that Rust doesn't fix the bug in Java. Even if you write rust code, you can also write buggy java code too so rust didn't fix the java code"

You're the only one here who thought "rust" meant "java semantics implemented in rust" in this context.

Re: Breaking java.lang.String

#59

Is this actually a bug? The default assumption in Java is that types are not thread-safe unless otherwise specified. Attempting to use types in a way that exceeds their documented thread safety has always been allowed to leave your program in an inconsistent state.

> Attempting to use types in a way that exceeds their documented thread safety has always been allowed to leave your program in an inconsistent state.

Wasn't there an attempt for Java to define the range of outcomes even of programs with data races?

Re: Breaking java.lang.String

#60
post #16

Out of interest, how should this be handled? Is this a bug in Java which should be fixed (looks like that to me)? My understanding was Java generally doesn't do "you did an undefined behaviour, so it's your fault", except for specifically marked very low-level interfaces.

Java definitely does "you wrote thread dangerous code, so it's your fault" for APIs not marked as being thread safe.

For what it's worth, Java does at least give some guarantees in case of data races -- the observed value will always be one that was explicitly set by one thread. This is different from most other languages, e.g. in C,C++, unsafe Rust it is UB.

Of course it can and still will result in invalid states.

Post reply on HN