4

Summary on resolution, I thought I was dealing with a Scala problem but it turns out Stopwatch and Scala Logging have private constructors, and I was not calling the proper public methods to instantiate them. gzm0's answer below points this out.


Trying to use Guava Stopwatch and Scala Logging, no matter whether I create a new Stopwatch() or new Logger() in Main or in an instantiated class I get this error with gradle run:

constructor Logger in class Logger cannot be accessed in class RedBlackTree4150
var loggerInst = new Logger()
constructor Stopwatch in class Stopwatch cannot be accessed in class RedBlackTree4150
var stopWatchInst = new Stopwatch()

If this is a duplicate of this or this question I don't know enough to realize it. I looked at this question but it doesn't have an accepted answer, and I tried (just for fun) to take my parens off my constructor calls to no avail.

Writing my first Gradle/Scala project for a Analysis of Algorithms assignment. I think if I was in Java I would be asking about static vs. non-static, not sure if that's the type of issue I am dealing with. Scala is not part of the assignment so I am not using a homework tag.

Here's how I am calling them and the first part of my program, the full .scala file and the build.gradle are on Github

import com.google.common.base.Stopwatch
import com.typesafe.scalalogging.slf4j.Logger
import scala.collection.immutable.TreeMap
import java.util.concurrent.TimeUnit

object Main extends App {
  // var rbtree = new RedBlackTree4150(logger, stopWatch)
  var rbtree = new RedBlackTree4150()
}
// class RedBlackTree4150 (var loggerInst: Logger, var stopWatchInst: Stopwatch) {
class RedBlackTree4150() {
  var loggerInst = new Logger()
  var stopWatchInst = new Stopwatch()

As you can see I have tried simplifying this by making it all one Object, and by instantiating Logger and Stopwatch in Main and passing them to the class (bad idea I know) but none of that works. What simple Scala thing am I missing here? Thanks.


Otherwise I believe I have all my dependencies in the project properly, and I get the same error on command line.

I do have one more error I posted as a separate question here, just in case it's relevant, the error is:

/home/jim/workspace/Scala/RedBlackTree4150/src/main/scala/Main.scala:36: value map is not a member of Double
  timingsMap = for (i <- powersList; j <- runTest(i)) yield i -> j
Community
  • 1
  • 1
JimLohse
  • 1,209
  • 4
  • 19
  • 44
  • `(for(i <- 10..20; j=runTest(i)) yield i -> j).toMap` – Eduardo Jan 25 '16 at 04:15
  • @Eduardo Wrong question LOL I will try that out, the other guys answer was accepted because of the explanation he was able to give about how the build interprets things ... you were very helpful too, how about this question? Thanks – JimLohse Jan 25 '16 at 04:16
  • Sorry. I am not familiar with Guava. It looks as if you were trying to access a private constructor directly. You may have to call some factory method to create instances instead. Some Java libraries work like that, but I'm not sure. – Eduardo Jan 25 '16 at 04:19
  • I don't think it's Guava or Stopwatch, I think it's something Scala-ish. Thanks! We'll see what turns up, editing my question on the other page to reflect the various suggestions. :) – JimLohse Jan 25 '16 at 04:21
  • I stand corrected thanks again @Eduardo gzm0 got this one too – JimLohse Jan 25 '16 at 04:25

1 Answers1

8

The constructors of both Stopwatch and Logger are private. You need to use factory methods to instantiate them.

In case of the Stopwatch, you could use the createUnstarted() method:

val stopwatch = Stopwatch.createUnstarted()

In case of Logger, you must use the apply method. However, it requires an underlying SLF4J logger. You can create one through SLF4J's LoggerFactory:

import org.slf4j.LoggerFactory
val logger = Logger(LoggerFactory.getLogger(getClass))
gzm0
  • 14,752
  • 1
  • 36
  • 64
  • I was trying to use createUnstarted and it was not resolving ... oh duh, yeah I was doing something stupid haha ... one down one to go, will accept and upvote now and comment when it's working!! I think part of my problem is that I am on Scala 2.10 so using an older version of Logger, let me try this out thanks again! – JimLohse Jan 25 '16 at 04:23
  • Do I need a Scala specific logger for any reason or can I just use what I would in Java? I am using both imports: `import org.slf4j.LoggerFactory` and `import com.typesafe.scalalogging.slf4j.Logger` and I assume I need this in my build.gradle: `'org.slf4j:slf4j-api:1.7.13'` gonna try it out now, I also can't find apply() in the spec for http://www.slf4j.org/api/org/slf4j/LoggerFactory.html – JimLohse Jan 25 '16 at 04:31
  • 1
    `com.typesafe.scalalogging.slf4j.Logger` is just a thin wrapper around any SLF4J logger (but isn't an SLF4J logger itself). The SLF4J logger is not Scala specific at all, so any way you instantiate a SLF4J logger (in Java) will do. – gzm0 Jan 25 '16 at 04:35
  • Well I will figure this out, was trying to implement scala-logging and for Scala 2.10 and earlier its not on MavenCentral (per https://github.com/typesafehub/scala-logging) so I probably am getting the wrong dependency. Thanks for all your help and if you have any more ideas, no hurry, have a good night – JimLohse Jan 25 '16 at 04:35
  • 1
    The `apply` method is on `Logger`. `X(y)` is a shorthand for `X.apply(y)` in Scala. – gzm0 Jan 25 '16 at 04:35
  • OK that's it, and I was still calling new. Now I have `val loggerInst = Logger.apply(LoggerFactory.getLogger(getClass))` and it works. And now I have completely different and very interesting and long errors! Progress! Thanks I am calling it a night. – JimLohse Jan 25 '16 at 04:39