How to turn a Ceylon class which extends a Java class into the Java class - ceylon

Suppose you have a Java method in a legacy library you need to use that takes a Class as an argument:
public void takeClass(Class<? extends JavaClass> cls);
Now, suppose you have a Ceylon class which extends JavaClass:
shared class CeylonClass() extends JavaClass() {}
Now, how can I use the method takeClass in Ceylon such that this works?
javaThing.takeClass( `class CeylonClass` );
// or maybe this should work?
javaThing.takeClass( javaClass<CeylonClass>() );
As shown above, I've been trying function javaClass in module ceylon.interop.java without success... if I do javaClass<JavaClass>() then it works, but this is no use for me, of course.
EDIT:
The error I get when using javaClass<CeylonClass>() as shown above:
argument must be assignable to parameter class of takeClass:
Class<CeylonClass> is not assignable to Class<JavaClass>?

Unfortunately, this is a case where you need to drop back to Java to add some glue. You can't, today, write it completely in Ceylon.
Explanation
The problem is that since Ceylon doesn't have use-site covariance, and since the Ceylon typechecker doesn't even understand Java's use-site covariance, the typechecker treats this method:
public void takeClass(Class<? extends JavaClass> cls);
As if it had this more restrictive signature:
public void takeClass(Class<JavaClass> cls);
Furthermore, the typechecker treats all Java classes as if they were invariant types.
Therefore, since javaClass<CeylonClass>() produces a Class<CeylonClass>, it's not considered assignable to the parameter of takeClass(). :-(
Workaround
The workaround is to add the following Java method:
public static <T extends JavaClass> void takeClass2(Class<T> cls) {
takeClass(cls);
}
Now this method can be called like this from Ceylon:
javaThing.takeClass2( javaClass<CeylonClass>() );
HTH
P.S.
While writing this up, I noticed that in fact java.lang.Class is actually a covariant type, and I think that Ceylon should easily be able to notice that too. So I created this issue:
https://github.com/ceylon/ceylon-compiler/issues/1474

Related

Unable to mock the local variable inside a method in java [duplicate]

I'm using Mockito 1.9.0. I want mock the behaviour for a single method of a class in a JUnit test, so I have
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
The problem is, in the second line, myClassSpy.method1() is actually getting called, resulting in an exception. The only reason I'm using mocks is so that later, whenever myClassSpy.method1() is called, the real method won't be called and the myResults object will be returned.
MyClass is an interface and myInstance is an implementation of that, if that matters.
What do I need to do to correct this spying behaviour?
Let me quote the official documentation:
Important gotcha on spying real objects!
Sometimes it's impossible to use when(Object) for stubbing spies. Example:
List list = new LinkedList();
List spy = spy(list);
// Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
// You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
In your case it goes something like:
doReturn(resultsIWant).when(myClassSpy).method1();
In my case, using Mockito 2.0, I had to change all the any() parameters to nullable() in order to stub the real call.
My case was different from the accepted answer. I was trying to mock a package-private method for an instance that did not live in that package
package common;
public class AnimalĀ {
void packageProtected();
}
package instances;
class Dog extends Animal { }
and the test classes
package common;
public abstract class AnimalTest<T extends Animal> {
#Before
setup(){
doNothing().when(getInstance()).packageProtected();
}
abstract T getInstance();
}
package instances;
class DogTest extends AnimalTest<Dog> {
Dog getInstance(){
return spy(new Dog());
}
#Test
public void myTest(){}
}
The compilation is correct, but when it tries to setup the test, it invokes the real method instead.
Declaring the method protected or public fixes the issue, tho it's not a clean solution.
The answer by Tomasz Nurkiewicz appears not to tell the whole story!
NB Mockito version: 1.10.19.
I am very much a Mockito newb, so can't explain the following behaviour: if there's an expert out there who can improve this answer, please feel free.
The method in question here, getContentStringValue, is NOT final and NOT static.
This line does call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
This line does not call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
For reasons which I can't answer, using isA() causes the intended (?) "do not call method" behaviour of doReturn to fail.
Let's look at the method signatures involved here: they are both static methods of Matchers. Both are said by the Javadoc to return null, which is a little difficult to get your head around in itself. Presumably the Class object passed as the parameter is examined but the result either never calculated or discarded. Given that null can stand for any class and that you are hoping for the mocked method not to be called, couldn't the signatures of isA( ... ) and any( ... ) just return null rather than a generic parameter* <T>?
Anyway:
public static <T> T isA(java.lang.Class<T> clazz)
public static <T> T any(java.lang.Class<T> clazz)
The API documentation does not give any clue about this. It also seems to say the need for such "do not call method" behaviour is "very rare". Personally I use this technique all the time: typically I find that mocking involves a few lines which "set the scene" ... followed by calling a method which then "plays out" the scene in the mock context which you have staged... and while you are setting up the scenery and the props the last thing you want is for the actors to enter stage left and start acting their hearts out...
But this is way beyond my pay grade... I invite explanations from any passing Mockito high priests...
* is "generic parameter" the right term?
One more possible scenario which may causing issues with spies is when you're testing spring beans (with spring test framework) or some other framework that is proxing your objects during test.
Example
#Autowired
private MonitoringDocumentsRepository repository
void test(){
repository = Mockito.spy(repository)
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
In above code both Spring and Mockito will try to proxy your MonitoringDocumentsRepository object, but Spring will be first, which will cause real call of findMonitoringDocuments method. If we debug our code just after putting a spy on repository object it will look like this inside debugger:
repository = MonitoringDocumentsRepository$$EnhancerBySpringCGLIB$$MockitoMock$
#SpyBean to the rescue
If instead #Autowired annotation we use #SpyBean annotation, we will solve above problem, the SpyBean annotation will also inject repository object but it will be firstly proxied by Mockito and will look like this inside debugger
repository = MonitoringDocumentsRepository$$MockitoMock$$EnhancerBySpringCGLIB$
and here is the code:
#SpyBean
private MonitoringDocumentsRepository repository
void test(){
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
Important gotcha on spying real objects
When stubbing a method using spies , please use doReturn() family of methods.
when(Object) would result in calling the actual method that can throw exceptions.
List spy = spy(new LinkedList());
//Incorrect , spy.get() will throw IndexOutOfBoundsException
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
I've found yet another reason for spy to call the original method.
Someone had the idea to mock a final class, and found about MockMaker:
As this works differently to our current mechanism and this one has different limitations and as we want to gather experience and user feedback, this feature had to be explicitly activated to be available ; it can be done via the mockito extension mechanism by creating the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line: mock-maker-inline
Source: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
After I merged and brought that file to my machine, my tests failed.
I just had to remove the line (or the file), and spy() worked.
One way to make sure a method from a class is not called is to override the method with a dummy.
WebFormCreatorActivity activity = spy(new WebFormCreatorActivity(clientFactory) {//spy(new WebFormCreatorActivity(clientFactory));
#Override
public void select(TreeItem i) {
log.debug("SELECT");
};
});
As mentioned in some of the comments, my method was "static" (though being called on by an instance of the class)
public class A {
static void myMethod() {...}
}
A instance = spy(new A());
verify(instance).myMethod(); // still calls the original method because it's static
Work around was make an instance method or upgrade Mockito to a newer version with some config: https://stackoverflow.com/a/62860455/32453
Bit late to the party but above solutions did not work for me , so sharing my 0.02$
Mokcito version: 1.10.19
MyClass.java
private int handleAction(List<String> argList, String action)
Test.java
MyClass spy = PowerMockito.spy(new MyClass());
Following did NOT work for me (actual method was being called):
1.
doReturn(0).when(spy , "handleAction", ListUtils.EMPTY_LIST, new String());
2.
doReturn(0).when(spy , "handleAction", any(), anyString());
3.
doReturn(0).when(spy , "handleAction", null, null);
Following WORKED:
doReturn(0).when(spy , "handleAction", any(List.class), anyString());

Jackson 1.9.0: JsonTypeInfo for abstract class not working with Lists

Using this abstract class:
#JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
#JsonSubTypes({ #JsonSubTypes.Type(value = PostingTaskInstanceDto.class, name = "TI") })
public abstract class BasePostingDto {}
and this inherited class:
public class PostingTaskInstanceDto extends BasePostingDto {}
I get correct serialization for a single object. This works, using Spring-MVC:
#RequestMapping("/{id}")
#ResponseBody
public BasePostingDto findById(#PathVariable("id") Long id) {
return createDto(postingService.findById(id));
}
But if I retrieve a List of BasePostingDto from the remote controller, the type property is missing:
#RequestMapping("/by-user/all")
#ResponseBody
public List<BasePostingDto> findByUser() {
return createDtoList(postingService.findByUser(AuthUtils.getUser()));
}
Why is this and how can I force the type property?
Update: the type property is also included if I change List<BasePostingDto> to BasePostingDto[], however I would prefer to go with the List.
It sounds like the framework you are using (and which uses Jackson under the hood) is not passing full generics-aware type information.
I don't know how that can be fixed (it is problem with integration by framework, and not something Jackson can address), but the usual work around is for you to use sub-class of List:
public class PostingDtoList extends List<BasePostingDto> { }
and use that in signature, instead of generic type. This solves the issue because then the generic type signature is retained (since it is stored in super type declaration, and accessible via type-erased PostingDtoList class!).
In generally I think it is best to avoid using generic List and Map types as root type (and instead use POJO); partly because of problems issued (there are bigger problems when using XML for example). But it can be made to work if need be.

Robotlegs wiring up dependencies that belong to a base class

I'm using robot legs, I've got a bunch of ServiceResponses that extends a base class and have a dependency on a Parser, IParser. I need to wire in a parser specific to the subclass. Here's an example:
ModuleConfigResponse extends SimpleServiceResponse and implements IServiceResponse.
The initial part is easy to wire in the context, here's an example:
injector.mapClass(IServiceResponse, ModuleConfigResponse);
injector.mapClass(IServiceResponse, SimpleServiceResponse, "roomconfig");
..etc
Each Response uses a parser that is used by the baseclass:
injector.mapValue(IParser, ModuleConfigParser, "moduleconfig");
injector.mapValue(IParser, RoomConfigParser, "roomconfig");
The question is how to tie these together. The base class could have:
[Inject]
public var parser : IParser
But I can't define the type ahead of time. Im wondering if there a nice way of wiring this in the context. For the moment I've decided to wire this up by instanciating responses in a ResponseFactory instead so that I pay pass the parser manually in the constructor.
injector.mapValue(IParser, ModuleConfigParser, "moduleconfig");
I realised that not everything can be mapped in the context, RL trapped me into this way of thinking. But I've realised that its far better to map a factory to produce these objects which have very specific dependencies, than littler the codebase with marker interfaces or strings :)
one solution is to have the following in your base class:
protected var _parser : IParser
Then for instance in ModuleConfigResponse
[Inject(name='moduleconfig')]
public function set parser( value : IParser ) : void{
_parser = value;
}
But TBH, using named injections is STRONGLY discouraged, you might as well use a marker interface:
public interface IModuleConfigParser extends IParser{}
the base class stays the same, but ModuleConfigResponse would then use:
[Inject]
public function set parser( value : IModuleConfigParser ) : void{
_parser = value;
}

OOP Proper use of interfaces in AS3

I'm designing a framework and in the process I have come across an interesting but most likely basic problem. I have a base class called CoreEngine and two other classes that extend it: CoreEngine1 and CoreEngine2. I created an interface that each of these classes would implement to increase the flexibility of my project. However, I have a problem... The definition of my methods in the interface do not match the definition in each inherited class! Each class must implement the following method:
function get avatar():AvatarBase;
The problem is that CoreEngine1 and CoreEngine2 expect a different type of avatar:
CoreEngine1
function get avatar():AvatarScaling
CoreEngine2
function get avatar():AvatarPlatform
As you can see, the return type for avatar in CoreEngine1 and CoreEngine2 do NOT match the type as specified in the interface. I was hoping that since both AvatarScaling and AvatarPlatform inherit AvatarBase that I wouldn't have a problem compiling. However, this is not the case. According to Adobe's documentation, the types MUST match the interface. I am trying to follow one of the core concepts of object oriented programming to extend the flexibility of my framework: "Program to an interface rather than an implementation". The first thing that comes to my mind is that the return type of the accessor method should be of an interface type (Maybe I just answered my own question).
I'm certain this is a common problem others have run into before. Architecturally, what do you think is the best way to solve this problem? Thanks in advance!
Regards,
Will
This is a limitation of how interfaces work and are declared.
If there's inheritance that can happen with the return types, as you've described with AvatarBase and subclasses, then I think the right approach is to make the return type the lowest common denominator and just handle the resulting object on the other end. So, if you're dealing with a CoreEngine1 object, you know you can cast the result from AvatarBase to AvatarScaling. Alternately, if you don't know the object type that you are calling get avatar() on, then you can type check the returned value. The type check would then only be needed if you're looking to call a method that exists on AvatarScaling but not on AvatarBase. I don't think returning an interface type will buy you much in this case because the only things that interface can implement would be things that all forms of Avatar share, which wouldn't be any different than methods in AvatarBase.
Like HotN and Dinko mentioned, it would be best to allow get avatar() to return AvatarBase allways and then cast the returned object as the concrete subclass.
Using Dinko's example:
public /* abstract */ class CoreEngine
{
public /* abstract */ function get avatar():AvatarBase {}
}
public function CoreEngine1 extends CoreEngine
{
override public function get avatar():AvatarBase { return new AvatarScaling(); }
}
public function CoreEngine2 extends CoreEngine
{
override public function get avatar():AvatarBase { return new AvatarPlatform(); }
}
public /* abstract */ class AvatarBase {}
public class AvatarScaling extends AvatarBase
{
public function someAvatarScalingMethod():void {}
}
public class AvatarPlatform extends AvatarBase
{
public function someAvatarPlatformMethod():void {}
}
To use a method from AvatarScaling, cast the returned object:
var c1:CoreEngine1 = new CoreEngine1();
var avatarScaling:AvatarScaling = AvatarScaling(c1.avatar());
avatarScaling.someAvatarScalingMethod();
hth
I think you answered your own question... the return type would still be AvatarBase, you need to follow the signature that you specified in the interface... but you can technically return ANY descendent of AvatarBase in that function. So doing something like
return new AvatarScaling();
in CoreEngine1 would be perfectly acceptable.
Of course in your calling function you will get back an AvatarBase instance, and you will have to know what this is in order to cast to a specific subclass.
CoreEngine1 ce1 = new CoreEngine1();
AvatarScaling avatar = ce1.avatar() as AvatarScaling;

actionscript-3: refactor interface inheritance to get rid of ambiguous reference error

imagine there are two interfaces arranged via composite pattern, one of them has a dispose method among other methods:
interface IComponent extends ILeaf {
...
function dispose() : void;
}
interface ILeaf {
...
}
some implementations have some more things in common (say an id) so there are two more interfaces:
interface ICommonLeaf extends ILeaf {
function get id() : String;
}
interface ICommonComponent extends ICommonLeaf, IComponent {
}
so far so good. but there is another interface which also has a dispose method:
interface ISomething {
...
function dispose() : void;
}
and ISomething is inherited by ICommonLeaf:
interface ICommonLeaf extends ILeaf, ISomething {
function get id() : String;
}
As soon as the dispose method is invoked on an instance which implements the ICommonComponent interface, the compiler fails with an ambiguous reference error because ISomething has a method called dispose and ILeaf also has a dispose method, both living in different interfaces (IComponent, ISomething) within the inheritace tree of ICommonComponent.
I wonder how to deal with the situation if
the IComponent, the ILeaf and the ISomething can't change.
the composite structure must also work for for the ICommonLeaf & ICommonComponent
implementations and the ICommonLeaf & ICommonComponent must conform to the ISomething type.
this might be an actionscript-3 specific issue. i haven't tested how other languages (for instance java) handle stuff like this.
You are searching for a solution to the Diamond Problem. C# has an approach to this but basically I would factor the method "dispose" out of your interfaces and create a new "IDisposable".
If the same name like "id" is used twice, it looks like a problem in your code with an ambiguous name. We started to add prefixes to properties and methods. Imagine you have a property "name" that belongs to two different things. Like the "displayName" and the "uniqueName".
This also helps with auto completion. If a DisplayObject is an ILayoutObject and yout type displayObject.layout you get everything layout releated.
It seems casting solves the ambiguity even though it's far from neat.
class SomeComponent implements ICommonComponent {}
var c : ICommonComponent = new SomeComponent();
trace(ISomething(c).dispose()); //compiles
trace(IComponent(c).dispose()); //compiles
trace(c.dispose()); //fails
As far as I'm aware, there's no neat way to deal with this problem in Actionscript.
The only thing I can think of is refactoring your interfaces to avoid name clashes, which, admitedly, it's not always possible.
Don't know about Java, but C# has a way to handle this through explicit interface implementation.