#2558 Java Class as a Field on a const class

jhughes Mon 29 Aug 2016

Been trying to understand concept of constant classes and their restrictions on fields you can implement. Searched quite a bit but couldn't find a clear enough example on how I would actually implement a java class as a field on a const class. What I have is a class that inherits WebMod and so it must be declared const. I need to be able to define a field created from an included java class but no matter what i've tried, I can't figure out how to accomplish this seemingly simple task. I've tried to out how use natives but couldn't figure out how or if that even would apply here and I can't define it as a const since it's a "non-constant type".

Anybody have an example of how this is accomplished?

jhughes Tue 30 Aug 2016

Really stuck on this as I need to be able to have a java class as a field that can be accessed when the onGet method is called from a Weblet. Does fantom support the ability to do this or am I trying to do something beyond it's scope?

SlimerDude Tue 30 Aug 2016

Const classes are immutable, that is, their contents can not change. They accomplish this by only allowing const fields, which themselves can only be instances of immutable const classes. I say a bit more in Confused About Const Classes?

Const classes exist to ensure mutable data is never leaked between threads - it is an important part of the Fantom language, and overcomes many of the threading and concurrency issues seen in other languages.

Java classes by their very nature, are always mutable. That means Java classes can not be held as a field on a Fantom const class.

There are some advanced techniques of accessing non-const data from a const class in a thread safe manner. But for now you should just start with Unsafe. Here's a quick example of you may set it in the ctor and access it later:

const class MyWebMod : WebMod {

    const Unsafe javaDataRef
    
    new make() {
        myJavaVal := ... <wotever> ...
        javaDataRef = Unsafe(myJavaVal)
    }

    override Void onGet() {
        javaData := javaDataRef.val
    }

}

If you need to change / reset the value held in Unsafe then you can wrap it in an AtomicRef.

jhughes Tue 30 Aug 2016

The Unsafe wrapper is exactly what I needed for this, thanks for showing me that. Is there documentation that talks about the advanced methods? Not sure i'll need it in this case but it might be good to know about if I do.

SlimerDude Tue 30 Aug 2016

documentation that talks about the advanced methods

It's all based on what the core concurrent pod has to offer. I mention some ideas in the article From One Thread to Another.... It's focussed on safely passing data between threads, which is what immutable classes are all about.

The article explains the raw concepts, but they've all been fully realised in the afConcurrent pod.

But thinking about it, you'll probably need to use Unsafe at some point because that's the only way to pass mutable state between threads.

I suppose you could use a const Fantom class with a native Java implementation, but that's pretty advanced. I find natives are really tricky to compile and get right, and it does no more for you (and isn't any safer) that just using Unsafe.

Login or Signup to reply.