This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Re: NullPointerException for AbstractPartialFunction.orElse in 20110108 trunk (2.10)

2 replies
tolsen77
Joined: 2008-10-08,
User offline. Last seen 1 year 38 weeks ago.
Changed nomatchMatcher and messageMatcher to defs but still same exception.

The highlighted line in AbstractPartialFunction is where the exception is thrown. I read the error as this.fallBackField somehow has not been set (null is its initial value). It is set in fallback, which in turn is only called from missingCase and isDefinedAt (conditionally).

abstract class AbstractPartialFunction[-T1, +R]
    extends AbstractFunction1[T1, R]
    with PartialFunction[T1, R]
    with Cloneable {

  private var fallBackField: PartialFunction[T1 @uncheckedVariance, R @uncheckedVariance] = _

  def fallBack: PartialFunction[T1, R] = synchronized {
    if (fallBackField == null) fallBackField = PartialFunction.empty
    fallBackField
  }

  override protected def missingCase(x: T1): R = fallBack(x)

  // Question: Need to ensure that fallBack is overwritten before any access
  // Is the `synchronized` here the right thing to achieve this?
  // Is there a cheaper way?
  override def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] = {
    val result = this.clone.asInstanceOf[AbstractPartialFunction[A1, B1]]
    result.synchronized {
      result.fallBackField = this.fallBackField orElse that
      result
    }
  }

  def isDefinedAt(x: T1): scala.Boolean = _isDefinedAt(x) || fallBack.isDefinedAt(x)
  def _isDefinedAt(x: T1): scala.Boolean

}

2012/1/8 √iktor Ҡlang <viktor [dot] klang [at] gmail [dot] com>

Avoid using abstract vals unless you're very comfortable with initialization order. Either use abstract def or lazy val.

Cheers,
V

On Jan 8, 2012 6:00 PM, "Trond Olsen" <trond [at] steinbit [dot] org> wrote:
In the classes that mixin the Resumable trait ala:

class A
  extends Some
  with Actor with Resumable {
    protected val messageMatcher: PartialFunction[Any, Unit] = {
        case msg =>
    }
}

2012/1/8 √iktor Ҡlang <viktor [dot] klang [at] gmail [dot] com>
Where are you assinging:
protected val messageMatcher: PartialFunction[Any, Unit]
?

On Sun, Jan 8, 2012 at 4:57 PM, Trond Olsen <trond [at] steinbit [dot] org> wrote:
I'm trying out the latest trunk but had some problems running my code. The code segment react(messageMatcher orElse nomatchMatcher) generates NullPointerException:

trait Resumable {
  this: scala.actors.Actor =>

  protected val monitor: scala.actors.Actor with Monitoring
  protected val messageMatcher: PartialFunction[Any, Unit]

  private final val nomatchMatcher: PartialFunction[Any, Unit] = {
    case Resumable.Exit => exit()
    case msg            => monitor.nomatchHandlers.foreach(f => f(this, msg))
  }

  final def act() {
    link(monitor)
    loop {
      react(messageMatcher orElse nomatchMatcher)
    }
  }
}

with the following stack trace:

Caused by: java.lang.NullPointerException
    at scala.runtime.AbstractPartialFunction.orElse(AbstractPartialFunction.scala:41)
    at project.ActorUtil$Resumable$$anonfun$act$1.apply(ActorUtil.scala:34)
    at project.ActorUtil$Resumable$$anonfun$act$1.apply(ActorUtil.scala:34)

Anyone able to spot the problem?

The AbstractPartialFunction is a new optimization for 2.10:

override def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] = {
  val result = this.clone.asInstanceOf[AbstractPartialFunction[A1, B1]]
  result.synchronized {
    result.fallBackField = this.fallBackField orElse that
    result
  }
}




--
Viktor Klang

Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang


Tobias Stenzel
Joined: 2012-01-09,
User offline. Last seen 42 years 45 weeks ago.
Re: NullPointerException for AbstractPartialFunction.orElse in 2

I noticed the same problem some weeks ago and filed an issue here:

https://issues.scala-lang.org/browse/SI-5300

On Jan 9, 1:33 am, Trond Olsen wrote:
> Changed nomatchMatcher and messageMatcher to defs but still same exception.
>
> The highlighted line in AbstractPartialFunction is where the exception is
> thrown. I read the error as this.fallBackField somehow has not been set
> (null is its initial value). It is set in fallback, which in turn is only
> called from missingCase and isDefinedAt (conditionally).
>
> abstract class AbstractPartialFunction[-T1, +R]
>     extends AbstractFunction1[T1, R]
>     with PartialFunction[T1, R]
>     with Cloneable {
>
>   private var fallBackField: PartialFunction[T1 @uncheckedVariance, R
> @uncheckedVariance] = _
>
>   def fallBack: PartialFunction[T1, R] = synchronized {
>     if (fallBackField == null) fallBackField = PartialFunction.empty
>     fallBackField
>   }
>
>   override protected def missingCase(x: T1): R = fallBack(x)
>
>   // Question: Need to ensure that fallBack is overwritten before any access
>   // Is the `synchronized` here the right thing to achieve this?
>   // Is there a cheaper way?
>   override def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]) :
> PartialFunction[A1, B1] = {
>     val result = this.clone.asInstanceOf[AbstractPartialFunction[A1, B1]]
>     result.synchronized {
> *      result.fallBackField = this.fallBackField orElse that*
>       result
>     }
>   }
>
>   def isDefinedAt(x: T1): scala.Boolean = _isDefinedAt(x) ||
> fallBack.isDefinedAt(x)
>   def _isDefinedAt(x: T1): scala.Boolean
>
> }
>
> 2012/1/8 √iktor Ҡlang
>
>
>
>
>
>
>
> > Avoid using abstract vals unless you're very comfortable with
> > initialization order. Either use abstract def or lazy val.
>
> > Cheers,
> > V
> > On Jan 8, 2012 6:00 PM, "Trond Olsen" wrote:
>
> >> In the classes that mixin the Resumable trait ala:
>
> >> class A
> >>   extends Some
> >>   with Actor with Resumable {
> >>     protected val messageMatcher: PartialFunction[Any, Unit] = {
> >>         case msg =>
> >>     }
> >> }
>
> >> 2012/1/8 √iktor Ҡlang
>
> >>> Where are you assinging:
>
> >>> protected val messageMatcher: PartialFunction[Any, Unit]
>
> >>> ?
>
> >>> On Sun, Jan 8, 2012 at 4:57 PM, Trond Olsen wrote:
>
> >>>> I'm trying out the latest trunk but had some problems running my code.
> >>>> The code segment react(messageMatcher orElse nomatchMatcher) generatesNullPointerException:
>
> >>>> trait Resumable {
> >>>>   this: scala.actors.Actor =>
>
> >>>>   protected val monitor: scala.actors.Actor with Monitoring
> >>>>   protected val messageMatcher: PartialFunction[Any, Unit]
>
> >>>>   private final val nomatchMatcher: PartialFunction[Any, Unit] = {
> >>>>     case Resumable.Exit => exit()
> >>>>     case msg            => monitor.nomatchHandlers.foreach(f => f(this,
> >>>> msg))
> >>>>   }
>
> >>>>   final def act() {
> >>>>     link(monitor)
> >>>>     loop {
> >>>>       react(messageMatcher orElse nomatchMatcher)
> >>>>     }
> >>>>   }
> >>>> }
>
> >>>> with the following stack trace:
>
> >>>> Caused by: java.lang.NullPointerException
> >>>>     at
> >>>> scala.runtime.AbstractPartialFunction.orElse(AbstractPartialFunction.scala:41)
> >>>>     at
> >>>> project.ActorUtil$Resumable$$anonfun$act$1.apply(ActorUtil.scala:34)
> >>>>     at project
> >>>> .ActorUtil$Resumable$$anonfun$act$1.apply(ActorUtil.scala:34)
>
> >>>> Anyone able to spot the problem?
>
> >>>> The AbstractPartialFunction is a new optimization for 2.10:
>
> >>>> override def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]) :
> >>>> PartialFunction[A1, B1] = {
> >>>>   val result = this.clone.asInstanceOf[AbstractPartialFunction[A1, B1]]
> >>>>   result.synchronized {
> >>>>     result.fallBackField = this.fallBackField orElse that
> >>>>     result
> >>>>   }
> >>>> }
>
> >>> --
> >>> Viktor Klang
>
> >>> Akka Tech Lead
> >>> Typesafe - Enterprise-Grade Scala from the
> >>> Experts
>
> >>> Twitter: @viktorklang

tolsen77
Joined: 2008-10-08,
User offline. Last seen 1 year 38 weeks ago.
Re: Re: NullPointerException for AbstractPartialFunction.orElse
After extempore's quick patch my project now unfortunately has no more bugs to report. ;)

On 9 January 2012 02:01, Tobias Stenzel <tobi [dot] stenzel [at] googlemail [dot] com> wrote:
I noticed the same problem some weeks ago and filed an issue here:

https://issues.scala-lang.org/browse/SI-5300


On Jan 9, 1:33 am, Trond Olsen <tr [dot] [dot] [dot] [at] steinbit [dot] org> wrote:
> Changed nomatchMatcher and messageMatcher to defs but still same exception.
>
> The highlighted line in AbstractPartialFunction is where the exception is
> thrown. I read the error as this.fallBackField somehow has not been set
> (null is its initial value). It is set in fallback, which in turn is only
> called from missingCase and isDefinedAt (conditionally).
>
> abstract class AbstractPartialFunction[-T1, +R]
>     extends AbstractFunction1[T1, R]
>     with PartialFunction[T1, R]
>     with Cloneable {
>
>   private var fallBackField: PartialFunction[T1 @uncheckedVariance, R
> @uncheckedVariance] = _
>
>   def fallBack: PartialFunction[T1, R] = synchronized {
>     if (fallBackField == null) fallBackField = PartialFunction.empty
>     fallBackField
>   }
>
>   override protected def missingCase(x: T1): R = fallBack(x)
>
>   // Question: Need to ensure that fallBack is overwritten before any access
>   // Is the `synchronized` here the right thing to achieve this?
>   // Is there a cheaper way?
>   override def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]) :
> PartialFunction[A1, B1] = {
>     val result = this.clone.asInstanceOf[AbstractPartialFunction[A1, B1]]
>     result.synchronized {
> *      result.fallBackField = this.fallBackField orElse that*
>       result
>     }
>   }
>
>   def isDefinedAt(x: T1): scala.Boolean = _isDefinedAt(x) ||
> fallBack.isDefinedAt(x)
>   def _isDefinedAt(x: T1): scala.Boolean
>
> }
>
> 2012/1/8 √iktor Ҡlang <viktor [dot] kl [dot] [dot] [dot] [at] gmail [dot] com>
>
>
>
>
>
>
>
> > Avoid using abstract vals unless you're very comfortable with
> > initialization order. Either use abstract def or lazy val.
>
> > Cheers,
> > V
> > On Jan 8, 2012 6:00 PM, "Trond Olsen" <tr [dot] [dot] [dot] [at] steinbit [dot] org> wrote:
>
> >> In the classes that mixin the Resumable trait ala:
>
> >> class A
> >>   extends Some
> >>   with Actor with Resumable {
> >>     protected val messageMatcher: PartialFunction[Any, Unit] = {
> >>         case msg =>
> >>     }
> >> }
>
> >> 2012/1/8 √iktor Ҡlang <viktor [dot] kl [dot] [dot] [dot] [at] gmail [dot] com>
>
> >>> Where are you assinging:
>
> >>> protected val messageMatcher: PartialFunction[Any, Unit]
>
> >>> ?
>
> >>> On Sun, Jan 8, 2012 at 4:57 PM, Trond Olsen <tr [dot] [dot] [dot] [at] steinbit [dot] org> wrote:
>
> >>>> I'm trying out the latest trunk but had some problems running my code.
> >>>> The code segment react(messageMatcher orElse nomatchMatcher) generatesNullPointerException:
>
> >>>> trait Resumable {
> >>>>   this: scala.actors.Actor =>
>
> >>>>   protected val monitor: scala.actors.Actor with Monitoring
> >>>>   protected val messageMatcher: PartialFunction[Any, Unit]
>
> >>>>   private final val nomatchMatcher: PartialFunction[Any, Unit] = {
> >>>>     case Resumable.Exit => exit()
> >>>>     case msg            => monitor.nomatchHandlers.foreach(f => f(this,
> >>>> msg))
> >>>>   }
>
> >>>>   final def act() {
> >>>>     link(monitor)
> >>>>     loop {
> >>>>       react(messageMatcher orElse nomatchMatcher)
> >>>>     }
> >>>>   }
> >>>> }
>
> >>>> with the following stack trace:
>
> >>>> Caused by: java.lang.NullPointerException
> >>>>     at
> >>>> scala.runtime.AbstractPartialFunction.orElse(AbstractPartialFunction.scala:41)
> >>>>     at
> >>>> project.ActorUtil$Resumable$$anonfun$act$1.apply(ActorUtil.scala:34)
> >>>>     at project
> >>>> .ActorUtil$Resumable$$anonfun$act$1.apply(ActorUtil.scala:34)
>
> >>>> Anyone able to spot the problem?
>
> >>>> The AbstractPartialFunction is a new optimization for 2.10:
>
> >>>> override def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]) :
> >>>> PartialFunction[A1, B1] = {
> >>>>   val result = this.clone.asInstanceOf[AbstractPartialFunction[A1, B1]]
> >>>>   result.synchronized {
> >>>>     result.fallBackField = this.fallBackField orElse that
> >>>>     result
> >>>>   }
> >>>> }
>
> >>> --
> >>> Viktor Klang
>
> >>> Akka Tech Lead
> >>> Typesafe <http://www.typesafe.com/> - Enterprise-Grade Scala from the
> >>> Experts
>
> >>> Twitter: @viktorklang

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland