Not able to create object of desired type in java

123 Views Asked by At

I'm using deequ to write analyzer. My editor is showing me this warning and I'm not sure how to fix this warning.

On line this:

Analyzer analyzer = new PatternMatch("email", Patterns.EMAIL(), option);

I get this warning in IntelliJ.

Raw use of parameterized class 'Analyzer' 

I get suggestion to change Analyzer to Analyzer<NumMatchesAndCount, DoubleMetric>. When I do that, this warning is solved, however, on doing that, I get an error in following line:

AnalysisRunBuilder analysisBuilder = AnalysisRunner.onData(table);
analysisBuilder.addAnalyzer(analyzer);

The error I get:

Required type:    Analyzer<?,Metric<?>>
Provided:         Analyzer<NumMatchesAndCount, DoubleMetric>

Also DoubleMetric implements Metric interface (public class DoubleMetric implements Metric, Product, Serializable), so we should not get the error described above in my opinion. Am I right?

Signature of addAnalyzer function in above line is:

public AnalysisRunBuilder addAnalyzer(Analyzer analyzer) {
      this.analyzers_$eq((Seq)this.analyzers().$colon$plus(analyzer, .MODULE$.canBuildFrom()));
      return this;
   }

My doubt is, when the signature of the function is not expecting parameterized class Analyzer, why am I getting warning that expected type is Analyzer<?,Metric<?>>?

My goal is to find out how exactly to use addAnalyzer function described above? In this function, I want to pass an instance of PatternMatch class. This class is implemented as follows: PatternMatch extends abstract class StandardScanShareableAnalyzerwhich implements interface ScanShareableAnalyzer which in turn extends Analyzer class.

1

There are 1 best solutions below

2
On

Deequ is a library written in Scala. While using Scala libraries from Java code is often possible, it isn't always straightforward.

The code you have for the addAnalyzer method above looks like it was generated from a byte code decompiler. Due to generics type erasure, method signatures in compiled bytecode lose their original type parameters. However, the type parameter information is included in metadata in the bytecode, which allows calls to be checked by the compiler. While it's possible in principle to reconstruct the original types in a decompiler (see Is it possible to decompile Java bytecode back to original generic type parameters), it appears that in this case, it has not.

The actual original (Scala) source code for AnalysisRunBuilder defines addAnalyzer like this:

def addAnalyzer(analyzer: Analyzer[_, Metric[_]]): this.type = {
  analyzers :+= analyzer
  this
}

In Scala, the syntax for parameter declarations takes the form: name: Type. Type parameters use square brackets instead of angle brackets. Wildcards use an underscore instead of a question mark. This method signature is equivalent to this signature in Java syntax:

public AnalysisRunBuilder addAnalyser(Analyzer<?, Metric<?>> analyzer)

Exactly the same as the error message indicates.

However, the definition of DoubleMetric shows that it extends Metric[Double]. I would expect the code in the question to compile successfully. Some Java IDEs have difficulty checking for compatibility with Java source code and Scala libraries. In IntelliJ IDEA, installing the official Scala plugin resolves many issues with false errors of this type. In most cases, using the command line javac compiler (or a build tool such as Maven that invokes it) avoids these issues.