https://github.com/scala/scala/blob/2.11.x/src/library/scala/Predef.scala#L230
??? in scala is a function defined in predef that throws a NotImplementedError
In my project I am using Google Guice in order to inject dependencies, and thought it would be good to have a similar function that throws an exception if the injection never happened, in order to catch missing usages of the injector or missing #Inject annotations.
In my project I have a class that is expecting to be injected
class OScoreboard {
#Inject
val source :Provider[ScoreboardBuilder] = injected;
}
and an object
class ExpectedInjectionException(message: String = null, cause: Throwable = null) extends RuntimeException
object injected extends Nothing{
def apply : Nothing = {
throw new ExpectedInjectionException("Expected an injection")
}
}
But I get the error that injected isn't of type Provider[ScoreboardBuilder]
Am I abusing apply? How else can I reference the scala function apply (or even with a different name) without referencing the object injected?
Also I suspect that even if I fix this error, the function will be eagerly run causing the exception before injection happens, does that mean I need to make every injected field lazy, or is there another solution?
Edit:
The problem was my understanding of Scala.
vals are eagerly computed, so the ???-like function is immediately executed on class construction (which since it's using field injection, occurs immediately before injection happens) causing the field to never be injected.
Values like final fields in Java CAN be injected, because it's only a restriction by the byte code verifier. final fields can be written to fine by using reflection (which Guice does).
In order to answer this question there needs to be a way to delay the execution of the ???-like function/value until the field is first read. I'm unsure how, or if it is even possible. The other option is just to initialize them to null. But that will result in NullPointerExceptions which are famously unhelpful. I was hoping to use a null-like error with an explanation that the injection failed.
First of all: in one place you wrote INJECTED and in the other place injected. I'll assume this was a typo and that you mean the same thing with both.
An assignment like this:
val source :Provider[ScoreboardBuilder] = INJECTED;
will not work because you are trying to assign the object INJECTED to a variable of type Provider[ScoreboardBuilder]. The object is not of that type, so you can't do that assignment.
Maybe you expected that the object would behave like a function and that its apply method would automatically be called, but that's not how it works.
You can define INJECTED as a method inside your class:
class OScoreboard {
#Inject
val source :Provider[ScoreboardBuilder] = INJECTED
private def INJECTED : Nothing =
throw new ExpectedInjectionException("Expected an injection")
}
Or you can put it in a separate object, but then you'd have to import it in your class:
object injected {
def INJECTED : Nothing =
throw new ExpectedInjectionException("Expected an injection")
}
class OScoreboard {
import injected._
#Inject
val source :Provider[ScoreboardBuilder] = INJECTED
}
The problem was my understanding of Scala.
vals are eagerly computed, so the ??? function is immediately executed on class construction (which since it's using field injection, occurs immediately before injection happens) causing the exception to be thrown.
Making it lazy results in the injection happening using reflection without the exception being thrown on construction. HOWEVER the generated Java code is not aware that this happens. So when the injected value is accessed for the first time, the generated code replaces the injected reference with ??? then proceeds to throw the exception.
There is no way that I can see in order to make this work.
Related
I have an #Embeddable class that uses property access to wrap another object that's not directly mappable by JPA via field access. It looks like this:
#Embeddable
#Access(AccessType.PROPERTY)
public class MyWrapper {
#NotNull
#Transient
private WrappedType wrappedField;
protected MyWrapper() {
}
public MyWrapper(WrappedType wrappedField) {
this.wrappedField = wrappedField;
}
#Transient
public WrappedType getWrappedField() {
return wrappedField;
}
public void setWrappedField(WrappedType wrappedField) {
this.wrappedField = wrappedField;
}
#Column(name = "wrappedTypeColumn")
protected String getJPARepresentation() {
return wrappedField.toString();
}
protected void setJPARepresentation(String jpaRepresentation) {
wrappedField = new WrappedType(jpaRepresentation);
}
}
Persisting an #Entity with a MyWrapper field works fine. But when I execute a query to load the Entity from the database, I get a NullPointerException. The stacktrace and some debugging shows that Eclipselink creates a new instance of MyWrapper by calling its default constructor and then calls the setJPARepresentation() method (as expected).
But now the unexpected happens: the stacktrace shows that the getJPARepresentation() is called from inside the setter, which then of course leads to a NullPointerException when return wrappedField.toString() is executed.
java.lang.NullPointerException
at MyWrapper.getJPARepresentation(MyWrapper.java:27)
at MyWrapper.setJPARepresentation(MyWrapper.java)
... 109 more
Fact is, there is obviously no call to the getter in the code and the stacktrace shows no line number indicating from where in the setter called the getter. So my conclusion would be, that the bytecode weaver of Eclipselink generated the call to the getter.
It's easy to build a workaround, but my question is: Why does Eclipselink do that?
P.S: I'm using EclipseLink 2.3.2.v20111125-r10461 in a GlassFish Server Open Source Edition 3.1.2 (build 23)
When weaving is enabled (default on Glassfish), EclipseLink will weave code into property get/set methods for,
change tracking
fetch groups (partial objects)
lazy (relationships)
For change tracking support the set method will be weaved to check if the new value is different than the old value, so it must call the get method to get the old value.
Now this is still odd, as since your are building a new object, I would not expect the change listener to be set yet, so would expect the change tracking check to be bypassed. You could decompile the code to see exactly what was generated.
The easiest fix is to just put in a null check in your get method, which is probably best in general for your code. You could also switch to field access, which will not have issues with side-affects in get/set methods. You could also use a Converter to handle the conversion, instead of doing the conversion in get/set methods.
UPDATE:
I have somewhat resolved the issue. Just in case if anyone runs in the same problem, here is the simplest solution: Looking at the MTApplcation source code, I have discovered that the initialize() method can be overloaded, taking a String parameter for the name of the class to instantiate. So if I create a separate class that extends MTApplication and pass it's name there, everything works correctly.
END OF UPDATE
I have a situation in Scala while trying to use a java library (MT4j, which is based on Processing). The library wants to instantiate the main class of the app (the caller-class):
Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(name);
applet = (PApplet) c.newInstance();
So as to refer it later in it's works.
However, it fails because, I guess, the main Scala class is not a class, but an object and due to library structure, it is necessary to call a static method initialize() of the main library class MTApplication. In Java static fields are located in classes, but in Scala - in objects. So it is impossible to instantiate an object and the library fails. In contrast to MT4j, Processing itself makes no calls to static methods on startup and successfully passes that phase.
If I just create a companion class, everything works fine except that the companion class does not get its fields initialized because the static initialize() method is called in companion object, the class instance just gets dead-born and the library becomes unusable.
At least that is how I understand this problem.
I get this error:
Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalAccessException: Class processing.core.PApplet can not access a member of class main.Main$ with modifiers "private"
at processing.core.PApplet.runSketch(PApplet.java:9103)
at processing.core.PApplet.main(PApplet.java:9292)
at org.mt4j.MTApplication.initialize(MTApplication.java:311)
at org.mt4j.MTApplication.initialize(MTApplication.java:263)
at org.mt4j.MTApplication.initialize(MTApplication.java:254)
at main.Main$.main(Main.scala:26)
at main.Main.main(Main.scala)
It is hard for me to explain also because I do not fully understand what is going on here. But anyone who has these libs can reproduce the situation in a couple of minutes, trying to launch the main class.
The abstract startUp() method which should be implemented to start the app, makes everything look even more sad. It initializes the object, but what the library tries to work with is an instance of the companion class which does not get initialized because in Scala the method belongs to the object.
My code:
object Main extends MTApplication {
def main(args: Array[String]) {
MTApplication.initialize()
new Main().startUp()
}
//this method is abstarct so it MUST be implemented,
override def startUp(){
}
}
class Main extends MTApplication {
override def startUp(){
//startup here
}
}
I am sorry if my explanations are vague, I just do not get it all completely. Probably to understand it is easier to repeat the experiment with MT4j library with Processing source code instead of the pre-linked 'core.jar' there to see what is happening inside. Doeas anyone have ideas on any workaround here?
Problem solved. Here is the solution:
object Main {
var current: MainC = _
def main(args: Array[String]) {
MTApplication.initialize("org.mttablescreen.main.MainC")
}
}
class MainC extends MTApplication {
//cons
Main.current = this
//cons ends
override def startUp(){
prepare
}
def prepare () {...}
}
I am testing a parser I have written in Scala using ScalaTest. The parser handles one file at a time and it has a singleton object like following:
class Parser{...}
object Resolver {...}
The test case I have written is somewhat like this
describe("Syntax:") {
val dir = new File("tests\\syntax");
val files = dir.listFiles.filter(
f => """.*\.chalice$""".r.findFirstIn(f.getName).isDefined);
for(inputFile <- files) {
val parser = new Parser();
val c = Resolver.getClass.getConstructor();
c.setAccessible(true);
c.newInstance();
val iserror = errortest(inputFile)
val result = invokeparser(parser,inputFile.getAbsolutePath) //local method
it(inputFile.getName + (if (iserror)" ERR" else " NOERR") ){
if (!iserror) result should be (ResolverSuccess())
else if(result.isInstanceOf[ResolverError]) assert(true)
}
}
}
Now at each iteration the side effects of previous iterations inside the singleton object Resolver are not cleaned up.
Is there any way to specify to scalatest module to re-initialize the singleton objects?
Update: Using Daniel's suggestion, I have updated the code, also added more details.
Update: Apparently it is the Parser which is doing something fishy. At subsequent calls it doesn't discard the previous AST. strange. since this is off topic, I would dig more and probably use a separate thread for the discussion, thanks all for answering
Final Update: The issue was with a singleton object other than Resolver, it was in some other file so I had somehow missed it. I was able to solve this using Daniel Spiewak's reply. It is dirty way to do things but its also the only thing, given my circumstances and also given the fact I am writing a test code, which is not going into production use.
According to the language spec, no, there is no way to recreate singleton objects. However, it is possible to reflectively invoke the constructor of a singleton, which overwrites the internal MODULE$ field which contains the actual singleton value:
object Test
Test.hashCode // => e.g. 779942019
val c = Test.getClass.getConstructor()
c.setAccessible(true)
c.newInstance()
Test.hashCode // => e.g. 1806030550
Now that I've shared the evil secret with you, let me caution you never, ever to do this. I would try very very hard to adjust the code, rather than playing sneaky tricks like this one. However, if things are as you say, and you really do have no other option, this is at least something.
ScalaTest has several ways to let you reinitialize things between tests. However, this particular question is tough to answer without knowing more. The main question would be, what does it take to reinitialize the singleton object? If the singleton object can't be reinitialized without instantiating a new singleton object, then you'd need to make sure each test loaded the singleton object anew, which would require using custom class loaders. I find it hard to believe someone would design something that way, though. Can you update your question with more details like that? I'll take a look again later and see if the extra details makes the answer more obvious.
ScalaTest has a runpath that loads classes anew for each run, but not a testpath. So you'll have to roll your own. The real problem here is that someone has designed this in a way that it is not easily tested. I would look at loading Resolver and Parser with a URLClassLoader inside each test. That way you'd get a new Resolver each test.
You'll need to take Parser & Resolver off of the classpath and off of the runpath. Put them into a directory of their own. Then create a URLClassLoader for each test that points to that directory. Then call findClass("Parser") on that class loader to get it. I'm assuming Parser refers to Resolver, and in that case the JVM will go back to the class loader that loaded Parser to get Resolver, which is your URLClassLoader. Do a newInstance on the Parser to get the instance. That should solve your problem, because you'll get a new Resolver singleton object for each test.
No answer, but I do have a simple example of where you might want to reset the singleton object in order to test the singleton construction in multiple, potential situations. Consider something stupid like the following code. You may want to write tests that validates that an exception is thrown when the environment isn't setup correctly and also write a test validates that an exception does not occur when the environment is not setup correctly. I know, I know everyone says, "Provide a default when the environment isn't setup correctly." but I DO NOT want to do this; it would cause issues because there would be no notification that you're using the wrong system.
object RequiredProperties extends Enumeration {
type RequiredProperties = String
private def getRequiredEnvProp(propName: String) = {
sys.env.get(propName) match {
case None => throw new RuntimeException(s"$propName is required but not found in the environment.")
case Some(x) => x
}
}
val ENVIRONMENT: String = getRequiredEnvProp("ENVIRONMENT")
}
Usage:
Init(RequiredProperties.ENVIRONMENT)
If I provided a default then the user would never know that it wasn't set and defaulted to the dev environment. Or something along these lines.
When executing the second line of this code Rhino Mocks throws an InvalidOperationException with a message "This action is invalid when the mock object is in replay state"
var mockScanner = MockRepository.GenerateMock<PortScanner>(null);
mockScanner.Expect((scanner => { scanner.Scan(null, null); }));
Stepping through the code in a debugger one can see the debugger run the method defined in the class and directly after control leaves this method the exception occurs.
This similar code in another test does work without issue
var mockView = MockRepository.GenerateMock<IScanView>(null);
mockView.Expect(view => { view.Close(); });
var controller = new ScanController(mockView);
controller.Exit();
mockView.VerifyAllExpectations();
The only difference that I can think of that might be of any consequense between theese two tests is that Exit is a member on an interface while Scan is a virtual member on a class
What am I missing?
Update
Further exploration has indicated that this is related to the way Rhino handles virtual methods. I am focusing mmy study of the documentation here now
The exception was caused because Rhino Mocks did not have the required level of access to the type in order to mock it properly. Granting internal access to the Rhino Mocks assembly using InternalsVisibleTo solved the problem.
It's noteworthy that this does not affect interfaces. I believe the reason for this is because the mocking framework needs to override the implementation on a class where there is none on an interface.
What happens if you remove the extra set of parentheses from the first expression?
var mockScanner = MockRepository.GenerateMock<PortScanner>(null);
mockScanner.Expect( scanner => { scanner.Scan(null, null); } );
I am using ScalaMock and Mockito
I have this simple code
class MyLibrary {
def doFoo(id: Long, request: Request) = {
println("came inside real implementation")
Response(id, request.name)
}
}
case class Request(name: String)
case class Response(id: Long, name: String)
I can easily mock it using this code
val lib = new MyLibrary()
val mock = spy(lib)
when(mock.doFoo(1, Request("bar"))).thenReturn(Response(10, "mock"))
val response = mock.doFoo(1, Request("bar"))
response.name should equal("mock")
But If I change my code to
val lib = new MyLibrary()
val mock = spy(lib)
when(mock.doFoo(anyLong(), any[Request])).thenReturn(Response(10, "mock"))
val response = mock.doFoo(1, Request("bar"))
response.name should equal("mock")
I see that it goes inside the real implementation and gets a null pointer exception.
I am pretty sure it goes inside the real implementation without matchers too, the difference is that it just doesn't crash in that case (any ends up passing null into the call).
When you write when(mock.doFoo(...)), the compiler has to call mock.doFoo to compute the parameter that is passed to when.
Doing this with mock works, because all implementations are stubbed out, but spy wraps around the actual object, so, the implementations are all real too.
Spies are frowned upon in mockito world, and are considered code smell.
If you find yourself having to mock out some functionality of your class while keeping the rest of it, it is almost surely the case when you should just split it into two separate classes. Then you'd be able to just mock the whole "underlying" object entirely, and have no need to spy on things.
If you are still set on using spies for some reason, doReturn would be the workaround, as the other answer suggests. You should not pass null as the vararg parameter though, it changes the semantics of the call. Something like this should work:
doReturn(Response(10, "mock"), Array.empty:_*).when(mock).doFoo(any(), any())
But, I'll stress it once again: this is just a work around. The correct solution is to use mock instead of spy to begin with.
Try this
doReturn(Response(10, "mock"), null.asInstanceOf[Array[Object]]: _*).when(mock.doFoo(anyLong(), any[Request]))