Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't find the required implicits #9

Open
aghasemi opened this issue Dec 4, 2018 · 13 comments
Open

Can't find the required implicits #9

aghasemi opened this issue Dec 4, 2018 · 13 comments

Comments

@aghasemi
Copy link

aghasemi commented Dec 4, 2018

Hi,
Intellij (and Maven) cannot, somehow, find the required implicits when I define a BeanConverter. I have imported me.limansky.beanpuree._. Any idea how I can debug this?

@limansky
Copy link
Owner

limansky commented Dec 4, 2018

You can try to start your investigation with check if LabelledBeanGeneric instance can be found for your class. And if LabelledGeneric is defined for your case class.

@aghasemi
Copy link
Author

aghasemi commented Dec 5, 2018

Thanks. Seems the issue is with the bean (LabelledBeanGeneric). Is there any criteria bean classes should meet? In my case, the class implements Serializable and fields are protected (instead of private), yet everything else is a typical bean.

@aghasemi
Copy link
Author

aghasemi commented Dec 5, 2018

Two other suspicions:

  1. Does it support multiple fields with the same type in a bean/case class?
  2. Does it (or JavaTypeMapper) support nesting?

@aghasemi
Copy link
Author

aghasemi commented Dec 5, 2018

Further tracking down, it seems the problem is the Align class. Any criteria here?

@limansky
Copy link
Owner

limansky commented Dec 5, 2018

Hm... As I remember Align is using only in StrictBeanConverter. Anyway there no limitations in Align or AlignByKey itself.

If I were you I would try to comment out pairs of getters and setters one by one to find the problem one.

@vtitov
Copy link

vtitov commented Dec 25, 2018

Similar issue.
I'm using "me.limansky" %% "beanpuree" % "0.4"
And for the following test:

package example

import org.scalatest._

import me.limansky.beanpuree._
import me.limansky.beanpuree.BeanConverter
import me.limansky.beanpuree.BeanConverter._

import scala.beans.BeanProperty

class Foo(@BeanProperty var a:Int, @BeanProperty var b: String) {override def toString = s"$a:$b"}
case class Bar(a: Int, b: String) {override def toString = s"$a:$b"}


class ConvTest extends WordSpecLike with Matchers {
  "Suite" should {
    "compare" in {
      val p = Bar(1,"a")
      val b = new Foo(1,"a")
      p.a shouldEqual b.getA
      p.b shouldEqual b.getB
    }
    "convert" in {
      val p = Bar(1,"a")
      val conv = BeanConverter[Foo, Bar]
      val b = conv.productToBean(p)
      p.a shouldEqual b.getA
      p.b shouldEqual b.getB
    }
  }
}

produces error:

beanpuree\CmdParserTest.scala:25:31: could not find implicit value for parameter sbc: me.limansky.beanpuree.BeanConverter[example.Foo,example.Bar]
[error]       val conv = BeanConverter[Foo, Bar]
[error]                               ^
[error] one error found
[error] (Test / compileIncremental) Compilation failed

When I comment out convert, Suite gets passed.
What is wrong?

@limansky
Copy link
Owner

Hi @vtitov

I've never tried to use beans created as a Scala classes with BeanProperty annotations. It looks like there is some difference between these classes and real Java beans. I'll investigate that. Thanks for isolating problem.

@limansky
Copy link
Owner

I've found that's wrong with your class: it doesn't have default constructor. Thus, it's not a JavaBean by definition: https://en.wikipedia.org/wiki/JavaBeans

They are serializable, have a zero-argument constructor, and allow access to properties using getter and setter methods.

If you change it:

scala> class Foo(@BeanProperty var a:Int, @BeanProperty var b: String) {override def toString = s"$a:$b";  def this() = this(0, "") }
defined class Foo

scala> val gen = BeanGeneric[Foo]
gen: me.limansky.beanpuree.BeanGeneric[Foo]{type Repr = Int :: String :: shapeless.HNil} = $anon$1@8ff9b6f

scala> gen.from(1 :: "aaa" :: HNil)
res2: Foo = 1:aaa

The reason of this behavior is that BeanGeneric (or LabelledBeanGeneric) uses the default constructor to create object from HList. In case of your class the generated code will be like:

val gen = new BeanGeneric[Foo] {
  override type Repr = Int :: String :: HNil
  override def to(foo: Foo): Repr = foo.getA :: foo.getB :: HNil
  override def from(repr: Repr) = repr match {
    case a :: b :: HNil =>
     val foo = new Foo()
     foo.setA(a)
     foo.setB(b)
     foo
  }
}

@limansky
Copy link
Owner

@aghasemi is it the same issue you have?

@limansky
Copy link
Owner

@vtitov Is this kind of classes are really used in your projects? I think it's possible to support it, if it really required.

@vtitov
Copy link

vtitov commented Jan 23, 2019

Mike,

No, it were not real classes. I faced similar problem while attempting to use beanpuree from pure Java. I try to use scala adapter object as a workaround.

@limansky
Copy link
Owner

@vtitov Could you provide problem Java class?

@vtitov
Copy link

vtitov commented Jan 31, 2019

@limansky, the issue was somewhat different:

...ConvTest.scala:15:46: could not find implicit value for parameter sbc: > me.limansky.beanpuree.BeanConverter[B,P]
[error] @BeanProperty val converter = BeanConverter[B, P]
[error] ^
[error] one error found

scala helper

class JavaBeanConverterHelper[B,P] {
  @BeanProperty val converter = BeanConverter[B, P]
}

java converter

package example;

import me.limansky.beanpuree.*;

public class JavaBeanConverter<B, P> {
    private BeanConverter<B, P> converter = new JavaBeanConverterHelper<B, P>().getConverter();

    public B productToBean(P p) { return converter.productToBean(p); }
    public P beanToProduct(B b) { return converter.beanToProduct(b); }
}

testcase

    "convert-java" in {
      val p = Bar(1,"a")
      val conv = new JavaBeanConverter[Foo, Bar]
      val b = conv.productToBean(p)
      p.a shouldEqual b.getA
      p.b shouldEqual b.getB
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants