question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

private val referred to by a WeakReference should still create a field

See original GitHub issue

In Scala 2, private variables in a class would be defined in the class. In Scala 3 they seem to be defined in the constructor.

I ran into this because I had weak references to the variables and then the variables got garbage collected - which was not what I wanted.

Compiler version

3.1.0-RC3

Minimized code

class Foo(i: Int) {
  private val bar: Int = 0
}

seems to give the equivalent in Java of…

public class Foo
{
    Foo(int i) {
        int bar = 0;
    }
}

when in Scala 2 it gave…

public class Foo
{
    private int bar = 0;

    Foo(int i) {
    }
}

I think Scala 2 also defined private[this] val in the class, not the constructor.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
Arthurm1commented, Oct 26, 2021

It was something like this…

class Foo(node: javafx.scene.Node) {
  // slider is added to `node` - so still referenced - so doesn't get GC'd
  private val slider = new javafx.scene.control.ScrollBar()
  node.getChildren.add(slider)
  // `prop` is only used here and never referenced outside this code snippet
  private val prop = new javafx.beans.property.SimpleDoubleProperty()
  prop.addListener(new javafx.beans.value.ChangeListener[Number] {
    override def changed(observable: javafx.beans.value.ObservableValue[_ <: Number], oldValue: Number, newValue: Number): Unit =
      dataChanged() // local method to update UI
  })
  // bind uses weak reference to link slider and prop
  slider.valueProperty().bindBidirectional(prop)
}

JavaFX uses weak references to bind a control to a property. In this case I was binding slider to prop which then called dataChanged to update the UI. So the scrollbar would work for a few seconds and then just stopped. Took me a while to realise that prop bind was disappearing after a GC because prop was not a class field like in Scala2.

I was just going to change my code as there are various workarounds, but it would mean that I have a public getter on prop, but that isn’t a big deal.

The weak reference to an Int was me trying to minimize the example.

My suggestion of being able to write something like private[class] val prop to force prop to be a class field was so that I could ensure this doesn’t happen again in the future with prop being optimised into the constructor.

1reaction
smartercommented, Oct 18, 2021

Ah right, WeakReference is magic, so maybe it should be special-cased by the compiler.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What's the difference between SoftReference and ...
A weak reference, simply put, is a reference that isn't strong enough to force an object to remain in memory. Weak references allow...
Read more >
Return value of shareIn&stateIn don't hold a strong reference ...
To prevent this issue, the instance of SharedFlow / StateFlow returned by shareIn and stateIn should have a private field that keeps a...
Read more >
WeakReference (Java SE 18 & JDK 18) - Oracle Help Center
Creates a new weak reference that refers to the given object. The new reference is not registered with any queue. Parameters: referent -...
Read more >
WeakReference Class (System) | Microsoft Learn
Represents a weak reference, which references an object while still allowing that object to be reclaimed by garbage collection.
Read more >
Bug descriptions — spotbugs 4.7.3 documentation
This public method declared in public enum unconditionally sets enum field, thus this field can be changed by malicious code or by accident...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found