Scala MapReduce : [error] method reduce overrides nothing - scala

I got stuck with this error, I wrote my TableReducer code like this:
class treducer extends TableReducer[Text, IntWritable, ImmutableBytesWritable]{
override def reduce(key: Text, values: java.lang.Iterable[IntWritable], context:Reducer[Text, IntWritable, ImmutableBytesWritable, Mutation]#Context){
var i=0
for (v <- values) {
i += v.get()
}
val put = new Put(Bytes.toBytes(key.toString())) // be sure to comment on toString.getBytes
put.add(Families.cf.bytes , Qualifiers.count.bytes, Bytes.toBytes(i))
context.write(null, put)
}
}
With this import:
import org.apache.hadoop.hbase.HBaseConfiguration
import org.apache.hadoop.hbase.client.HBaseAdmin
import org.apache.hadoop.hbase.client.HTable
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.hbase.client.Put
import org.apache.hadoop.hbase.client.Get
import java.io.IOException
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.hbase._
import org.apache.hadoop.hbase.client._
import org.apache.hadoop.hbase.io._
import org.apache.hadoop.hbase.mapreduce._
import org.apache.hadoop.io._
import scala.collection.JavaConversions._
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat
import org.apache.hadoop.mapreduce.Job
import org.apache.hadoop.mapreduce.Mapper
import org.apache.hadoop.mapreduce.ReduceContext
import org.apache.hadoop.mapreduce.Reducer
But got this error:
[error] /home/ans4175/activator/scala-hbase/src/main/scala/com/example/Hello.scala:85: method reduce overrides nothing.
[error] Note: the super classes of class treducer contain the following, non final members named reduce:
[error] protected[package mapreduce] def reduce(x$1: org.apache.hadoop.io.Text,x$2: Iterable[org.apache.hadoop.io.IntWritable],x$3: org.apache.hadoop.mapreduce.Reducer[org.apache.hadoop.io.Text,org.apache.hadoop.io.IntWritable,org.apache.hadoop.hbase.io.ImmutableBytesWritable,org.apache.hadoop.io.Writable]#Context): Unit
[error] override def reduce(key: Text, values: java.lang.Iterable[IntWritable], context:Reducer[Text, IntWritable, ImmutableBytesWritable, Mutation]#Context){
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
I don't know whats the problem. I have followed like this post
https://github.com/rawg/scala-hbase-wordcount/blob/master/src/main/scala/WordCountReducer.scala,
https://github.com/vadimbobrov/calc/blob/master/src/main/scala/com/os/job/InterpolatorReducer.scala
Thank you in advance

The error provides your answer. You've incorrectly declared one of the arguments.
The compiler has indicated that the third argument's type is:
Reducer[Text,IntWritable,ImmutableBytesWritable,Writable]#Context
Your override declares a method with a third argument of this type:
Reducer[Text, IntWritable, ImmutableBytesWritable, Mutation]#Context
Changing Mutation to Writable will allow the compiler to override the correct method.

when you override some method in a child class that means that same method must be there in parent class with same signature and your program is failing in that only.
this kind of errors typically indicates that signature of method in child is not matching with that in parent class, hence technically speaking you are not overriding anything and hence scala is telling you that
[error] /home/ans4175/activator/scala-hbase/src/main/scala/com/example/Hello.scala:85: method reduce overrides nothing.
Note: the super classes of class treducer contain the following, non final members named reduce:

Related

Initialising variables in a mock class scala

I am writing unit tests for an akka actor model implementation. The system contains classes and traits that need to be initialised. My issue lies with the testing of the methods. When I mock required parameters for a class, it removes the intelij compiler error, however all of the variables are set to null.
I have attempted to use
when(mock.answer).thenReturn(42)
and directly assigning the variables
val mock.answer = 42
The above two through compilation errors. "When" is not recognised and directly assigning values cases a runtime error.
Any insight would be much appreciated.
I am not sure if I understood your issue correctly, but try the self contained code snippet below and let me know if it is not clear enough:
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.mockito.MockitoSugar
import org.scalatest.{FunSuite, Matchers}
import org.mockito.Mockito.when
#RunWith(classOf[JUnitRunner])
class MyTest extends FunSuite with Matchers with MockitoSugar {
trait MyMock {
def answer: Int
}
test("my mock") {
val myMock = mock[MyMock]
when(myMock.answer).thenReturn(42)
myMock.answer should be(42)
}
}

How to use Status in own code in Play

Playversion is 2.6.12.
I want to use Results.Status in my own code like
// in my code somewhere
def doSomething(status:Results.Status) { ....}
// in controller
doSomething(Ok) <---- results in error
But I the Ok inside a controller seems not to be of type Results.Status
[error] found : MyController.this.Status
[error] required: play.api.mvc.Results.Status
Any ideas how to use Status in my own code outside controllers?
The helper code is
import org.scalactic.{Bad, Good, Or}
import play.api.libs.json.Json
import play.api.mvc.Result
import play.api.mvc.Results.Status
object Helper {
def toResult[T](r:Or[T, Result], s:Status):Result = {
r match {
case Good(entity) => s(Json.toJson(entity))
case Bad(badRequest) => badRequest
}
}
}
The controller code definition is extending
class AuthBaseController #Inject()(acc: AuthControllerComponents) extends BaseController with AuthRequestMarkerContext {
where BaseController leads to
trait ControllerHelpers extends Results with HttpProtocol with Status with HeaderNames with ContentTypes with RequestExtractors with Rendering with RequestImplicits
extending Status.
You can always explicitly pass the requested type:
doSomething(play.api.mvc.Results.Ok)
I suppose if you just import play.api.mvc.Results._ in your controller, you will have an import conflict (you can still try it), but just importing play.api.mvc.Results, and then using it like this
doSomething(Results.Ok)
should work.
[error] found : MyController.this.Status
[error] required: play.api.mvc.Results.Status
Status is a specific type that depends on the controller. To have a function that's a certain type, that doesn't care about the parent type you can use the # symbol like this:
def doSomething(status:Results#Status) { ....}

`exception during macro expansion: [error] scala.reflect.macros.TypecheckException` when using quill

I'm pretty new to Scala, Play, and Quill and I'm not sure what I'm doing wrong. I have my project split up into models, repositories, and services (and controllers, but that is not relevant for this question). Right now, I'm getting this error for the lines in my services that are making changes to the database:
exception during macro expansion: scala.reflect.macros.TypecheckException: Can't find implicit `Decoder[models.AgentId]`. Please, do one of the following things:
1. ensure that implicit `Decoder[models.AgentId]` is provided and there are no other conflicting implicits;
2. make `models.AgentId` `Embedded` case class or `AnyVal`.
And I'm getting this error for all the other lines in my services:
exception during macro expansion: [error] scala.reflect.macros.TypecheckException: not found: value quote
I found a similar ticket, but the same fix does not work for me (I am already requiring ctx as an implicit variable, so I can't import it as well. I'm totally at a loss and if anyone has any suggestions, I would be happy to try anything. I'm using the following versions:
Scala 2.12.4
Quill 2.3.2
Play 2.6.6
The code:
db/package.scala
package db
import io.getquill.{PostgresJdbcContext, SnakeCase}
package object db {
class DBContext(config: String) extends PostgresJdbcContext(SnakeCase, config)
trait Repository {
val ctx: DBContext
}
}
repositories/AgentsRepository.scala
package repositories
import db.db.Repository
import models.Agent
trait AgentsRepository extends Repository {
import ctx._
val agents = quote {
query[Agent]
}
def agentById(id: AgentId) = quote { agents.filter(_.id == lift(id)) }
def insertAgent(agent: Agent) = quote {
query[Agent].insert(_.identifier -> lift(agent.identifier)
).returning(_.id)
}
}
services/AgentsService.scala
package services
import db.db.DBContext
import models.{Agent, AgentId}
import repositories.AgentsRepository
import scala.concurrent.ExecutionContext
class AgentService(implicit val ex: ExecutionContext, val ctx: DBContext)
extends AgentsRepository {
def list: List[Agent] =
ctx.run(agents)
def find(id: AgentId): List[Agent] =
ctx.run(agentById(id))
def create(agent: Agent): AgentId = {
ctx.run(insertAgent(agent))
}
}
models/Agent.scala
package models
import java.time.LocalDateTime
case class AgentId(value: Long) extends AnyVal
case class Agent(
id: AgentId
, identifier: String
)
I am already requiring ctx as an implicit variable, so I can't import it as well
You don't need to import a context itself, but everything which is inside in order to make it work
import ctx._
Make sure to place it before ctx.run called, as in https://github.com/getquill/quill/issues/998#issuecomment-352189214

How do I iterate through the lines of a file in Scala using a custom newline delimeter?

I'd like to iterate over all the lines of a file in Scala but using the newline separator \n%\n instead of just \n. I'd like to be able to do this using the scala.io.Source abstract class.
Here's what I have so far:
object Main extends App {
val lines = Source.fromFile("quotes.txt").getLines
for {
line <- lines
} println(line)
}
This works fine using \n as a newline separator.
It seems that to be able to change the separator, I have to subclass scala.io.Source.LineIterator and implement my own isNewLine method.
However, when I try to subclass LineIterator like this:
import scala.io.Source
import scala.io.Source.LineIterator
class MyLineIterator extends LineIterator {
override def isNewLine(c: Char) = c == "\n%\n"
}
I get the following error when trying to build with sbt:
[info] Compiling 1 Scala source to /.../target/scala-2.12/classes...
[error] /.../Main.scala:6: value LineIterator is not a member of object scala.io.Source
[error] import scala.io.Source.LineIterator
[error] ^
[error] /.../Main.scala:8: not found: type LineIterator
[error] class MyLineiterator extends LineIterator {
[error] ^
[error] two errors found
Could somebody tell me why I can't import LineIterator and also provide a code snippet that allows me to specify a custom delimiter when iterating over the lines of a file?
Thanks for any help in advance.

How to instantiate lexical.Scanner in a JavaTokenParsers class?

I am writing a parser which inherits from JavaTokenParsers in that I have a function as follow:
import scala.util.parsing.combinator.lexical._
import scala.util.parsing._
import scala.util.parsing.combinator.RegexParsers;
import scala.util.parsing.combinator.syntactical.StdTokenParsers
import scala.util.parsing.combinator.token.StdTokens
import scala.util.parsing.combinator.lexical.StdLexical
import scala.util.parsing.combinator.lexical.Scanners
import scala.util.parsing.combinator.lexical.Lexical
import scala.util.parsing.input._
import scala.util.parsing.combinator.syntactical._
import scala.util.parsing.combinator.token
import scala.util.parsing.combinator._
class ParseExp extends JavaTokenParsers{
//some code for parsing
def parse(s:String) = {
val tokens = new lexical.Scanner(s)
phrase(expr)(tokens)
}
}
I am getting the following error :
type Scanner is not a member of package scala.util.parsing.combinator.lexical
[error] val tokens = new lexical.Scanner(s)
[error] ^
Why I have this error while I have imported all packages?
The JavaTokenParsers does not implement the Scanners trait. So you would need to extends also from this trait (or a trait that extends it) in order to have access to this class.
Unless your expr parser accepts the Reader as a parameter (not from its apply method), you'd need to override the type of elements and the input type if I'm not mistaken to make this working.
Also is there any reason you need to have a Reader[Token]?.
If you don't need a Reader[Token]and since you give your input in a plain string,
phrase(expr)(new CharSequenceReader(s))
should work.