Is it possible to override a method from interface at runtime? - java

I wonder if it is possible to override a method from an interface. I'm developing a plugin application for Confluence Data Center, and I need to maintain backward compatibility with the older version of Confluence, some of the interfaces are only available in the latest version of Confluence SDK, and I need to implement it dynamically(check the version, if it's an old version, use old interface)
this is the interface I need to implement:
public interface SiteSearchPermissionsQueryFactory {
SearchQuery create();
}
I have a class implementing the interface:
public class SiteSearchPermissionQueryFactory implements SiteSearchPermissionsQueryFactory {
final private SearchQuery searchQuery;
public SiteSearchPermissionQueryFactory(SearchQuery searchQuery){
this.searchQuery = searchQuery;
}
#Override
public SearchQuery create() {
return searchQuery;
}
}
As SiteSearchPermissionsQueryFactory is a new interface and only available on the latest version of Confluence SDK, and now I need to implement this interface and its override method create() dynamically on runtime(if my plugin application runs on latest version of Confluence).
I can check the instance of SiteSearchPermissionsQueryFactory like this:
public static SearchQuery getCompatibleQuery() {
try {
Class<?> permissionQueryFactory = Class.forName("SiteSearchPermissionsQueryFactory");
Object instance = Proxy.newProxyInstance(permissionQueryFactory.getClassLoader(), new Class<?>[]{permissionQueryFactory}, new InvocationHandler() {
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//Handle the invocations
if(method.getName().equals("create")){
return 1;
}
else return -1;
}
});
} catch (Exception e) {
return null;
}
}
But I have no idea how to override the create() method. Any help would be appreciated!

Related

Ways to Avoid if-else, switch-case in Factory design pattern

I am designing a validation module. It has 100 error codes(i.e. errcd_01, errcd_02,..,errcd_100) to be validated. In input I am getting a specific error code(i.e. errcd_01) out of above 100.
Module should perform validation for that specific error code.
I am using factory pattern.
/* Interface */
public interface validateErrCd {
void check_errcd();
}
/* Concrete classes implementing the same interface */
public class validateErrCd_01 implements validateErrCd {
#Override
public void check_errcd() {
//business logic related to errcd_01
}
}
public class validateErrCd_02 implements validateErrCd {
#Override
public void check_errcd() {
//business logic related to errcd_02
}
}
.
.
.
public class validateErrCd_100 implements validateErrCd {
#Override
public void check_errcd() {
//business logic related to errcd_100
}
}
/* Factory */
public class ErrorValidationFactory {
//use check_errcd method to get object of type shape
public validateErrCd getValidation(String errorCode){
if(errorCode == null){
return null;
}
if(errorCode.equalsIgnoreCase("errcd_01")){
return new validateErrCd_01();
} else if(errorCode.equalsIgnoreCase("errcd_02")){
return new validateErrCd_02();
} ..
.......
else if(errorCode.equalsIgnoreCase("errcd_100")){
return new validateErrCd_100();
}
else {
return null;
}
}
}
/* I am using the Factory to get object of concrete class by passing an specific error code to be validated (i.e. "errcd_01"). */
public class FactoryPatternDemo {
public static void main(String[] args) {
ErrorValidationFactory errorFactory = new ErrorValidationFactory();
//get an object of validateErrCd_01 and call its check_errcd method.
validateErrCd errcd01 = errorFactory.getValidation("errcd_01");
//call check_errcd method of validateErrCd_01
errcd01.check_errcd();
}
}
Now due to multiple if/else inside Factory class ErrorValidationFactory, I am getting couple of CI/CD errors while performing mvn clean install.
e.g. [MethodLength] - checkstyle, Rule:CyclomaticComplexity - PMD.
So is there a way I can replace if/else, switch case kind of decision making inside factory which does not trigger above CI/CD errors in Java?
Note : If possible I would like to avoid reflection
You could use a Map:
public class ErrorValidationFactory {
private Map<String,Supplier<validateErrCd>> creators=new HashMap<>();
public ErrorValidationFactory(){
creators.put("errcd_100",validateErrCd_100::new);
//Same for others
}
//use check_errcd method to get object of type shape
public validateErrCd getValidation(String errorCode){
if(errorCode == null){
return null;
}
return creators.getOrDefault(errorCode,()->null);
}
}
Supplier is a functional interface that contains a method returning an object. SomeClass::new or ()->new SomeClass() means that the constructor of the class will be used for that.
This allows to to create the instances later.
If you want to create the Map only once, you can make it static and populate it in a static initializer.
However, if you really want to dynamically get the constructors, you would need to use reflection.

Java - How to test exception which never will occur?

I have Utils class with method which throws exception when given data are incorrect.
I have also Service which uses this method, but the data are always generated in way that they will be correct during call. Data are generated by another utils class.
I understand that I should throw this exception from Utils class - but I can't throw it from Service - so I have to catch it.
How can I test this, simulate this exception?
All actions on this data are in private methods.
I want to avoid PowerMock, because I heard that it's a sign of bad design.
So the question is, how to implement this in good design?
From your description it looks like this:
class Service {
public void someMethod() {
Data data = AnotherUtils.getData();
try {
Utils.method(data); // exception never thrown
} catch(Exception e) {
// how to test this branch?
}
}
}
The goal would be something like this:
interface DataProvider {
Data getData();
}
interface DataConsumer {
void method(Data data);
}
class Service {
private final DataProvider dataProvider;
private final DataConsumer dataConsumer;
public Service(DataProvider dataProvider, DataConsumer dataConsumer) {...}
public void someMethod() {
Data d = dataProvider.getData();
try {
dataConsumer.method(data);
} catch(Exception e) {
}
}
}
This technique is called dependency injection.
Then, when testing, you can simply provide a mock implementation for this DataProvider interface that does return faulty data:
#Test(expected=Exception.class)
public void myTest() {
DataProvider badDataProvider = () -> new BadData(); // Returns faulty data
Service service = new Service(badDataProvider, Utils.getConsumer());
service.someMethod(); // boom!
}
For the non-testing code, you could simply wrap the utils classes you already have in these interfaces:
class AnotherUtils {
public static Data getData() {...}
public static DataProvider getProvider() {
return AnotherUtils::getData;
}
}
...
Service service = new Service(AnotherUtils.getProvider(), Utils.getConsumer());
Here is an approach where you want to introduce Dependency Injection, but for whatever reason you don't want to change legacy code.
Say you have some static utility method like so:
class Utils{
public static Something aMethod(SomethingElse input) throws AnException{
if(input.isValid())
return input.toSomething();
throw new AnException("yadda yadda");
}
}
And you have a class that uses that utility method. You can still inject it with a FunctionalInterface.
#FunctionalInterface
interface FunctionThrowsAnException<K,V> {
V apply(K input) throws AnException;
}
class Service {
private final FunctionThrowsAnException<SomethingElse,Something> func;
Service(FunctionThrowsAnException<SomethingElse,Something> func){
this.func = func;
}
Something aMethod(SomethingElse input){
try{
return func.apply(input);
}catch(AnException ex){
LOGGER.error(ex);
}
}
}
Then use it like this:
new Service(Utils::aMethod).aMethod(input);
To test it:
new Service(x -> { throw new AnException("HA HA"); }).aMethod(input);

The method must override a superClass method for ModelResolver interface

I am trying to create a class that implements the 'ModelResolver' interface
See http://maven.apache.org/ref/3.0.4/maven-model-builder/apidocs/org/apache/maven/model/resolution/ModelResolver.html
Here is the class
class MyResolver implements ModelResolver {
private final File artifactFile;
public MyResolver(File artifactFile) {
this.artifactFile = artifactFile;
}
#Override
public void addRepository(Repository arg0)
throws InvalidRepositoryException {
/** Nothing to do here as aether will take care of this. */
}
#Override
public void addRepository(Repository arg0, boolean arg1)
throws InvalidRepositoryException {
/** Nothing to do here as aether will take care of this. */
}
#Override
public ModelResolver newCopy() {
return this;
}
#Override
public ModelSource resolveModel(Parent parent)
throws UnresolvableModelException {
Artifact artifact;
try {
/** Use parent class getRemoteArtifact method */
artifact = getRemoteArtifact(parent.getGroupId(),
parent.getArtifactId(),
parent.getVersion(),
"pom");
} catch (ArtifactResolutionException e) {
throw new UnresolvableModelException(e.getMessage(),
parent.getGroupId(),
parent.getArtifactId(),
parent.getVersion());
}
return new FileModelSource(artifact.getFile());
}
#Override
public ModelSource resolveModel(String groupId,
String artifactId,
String version)
throws UnresolvableModelException {
return new FileModelSource(artifactFile);
}
}
This gives me the following error
The method addRepository must override the super class method.
I am on java 1.7 and using eclipse for my development. What am I missing?
I also verifies that the compiler compliance level is set to 1.7 in eclipse

Porting Java to C# for Xamarin Android Library

I created an Android Binding Library for my Xamarin project, using an AAR.
I am now trying to implement that library.
Here is the java snippet of code using the library:
The java code:
new AsyncOperation.CompletionHandler<RouteManager>(){
#Override
public void success(RouteManager result){
result.subscribe(ACCEL_DATA, new RouteManager.MessageHandler(){
#Override
public void process(Message message){
Log.i(LOG_TAG,message)
}
}
}
I am trying to port this code to C#.
My C# code, from C# wrapper created from binding library:
class AsyncOperationHandler : AsyncOperationCompletionHandler
{
public override unsafe void Success(Object p0)
{
try
{
var routeManger = (IRouteManager)p0;
routeManger.Subscribe(ACCEL_DATA, new RouteMessageHandler());
}
catch (Exception)
{
Log.Error(LOG_TAG, "Error");
}
}
}
class RouteMessageHandler : IRouteManagerMessageHandler
{
public void Dispose()
{
throw new NotImplementedException();
}
public IntPtr Handle { get; }
public void Process(Message p0)
{
var message = p0;
Log.Info(LOG_TAG, message);
}
}
I am getting an error in the C# wrapper on the routeManger.Subscribe line.
When the RouteManagerMessageHandler gets initialized, it gets the Handle, then throws a null pointer exception inside the Binding Library.
Is this the correct way to port a Java Interface to C#?
If you implement a Java Interface, you have to derive from Java.Lang.Object.
class RouteMessageHandler : Java.Lang.Object, IRouteManagerMessageHandler
{
public void Process(Message p0)
{
var message = p0;
Log.Info(LOG_TAG, message);
}
}
There should be something on the compile output.
Type 'AppXYZ.RouteMessageHandler' implements IRouteManagerMessageHandler but does not inherit from Java.Lang.Object. It is not supported.

How to pass and invoke method references in Java

Let's say I have a class called Server, and I would like to allow others to write Plugins for it. Say Plugin is an Interface that extends Runnable and adds a single method: void init(...). It is the job of a plugin to collect data and send it to the server. When the time comes to send data to the server, however, how does it do this? Coming from C and C++ I am looking for a thinking along the lines of a function pointer. It seems to be possible in Java though I have not found examples outside the Java Standard Class Library.
How do I pass a method reference to the init method such that it can be stored by the Plugin, and then how do I invoke the method whenever the Plugin wants to send data? For now say that the desired Server method is: void sendData(Integer data).
For example:
// Inside Server
Plugin p = new PluginImplementation();
p.init(this::sendData);
// Plugin init
public void init(?? sendMethod) {
storedSendMethod = sendMethod;
// ...
}
// Plugin run
public void run() {
// ...
storedSendMethod(x) // Sends data to server
// ...
}
Using java.util.function.Function we can pass a function as an argument to a method, and then use apply() to apply it to the relevant arguments. Here's an example:
import java.util.function.Function;
public class FunctionDemo {
// we will pass a reference to this method
public static Integer square(Integer x) {
return x * x;
}
// this method accepts the function as an argument and applies it to the input: 5
public static Integer doSomething(Function<Integer, Integer> func) {
return func.apply(5);
}
public static void main(String[] args) {
// and here's how to use it
System.out.println(doSomething(FunctionDemo::square)); // prints 25
}
}
Additional version with multiple parameters (passed as an array):
public static Integer sum(Integer[] x) {
Integer result = 0;
for(int i = 0; i < x.length; i++)
result += x[i];
return result;
}
public static void main(String[] args) {
Integer[] arr = {1,2,3,4,5};
System.out.println(doSomething(Play::sum, arr));
}
public static Integer doSomething(Function<Integer[], Integer> func,
Integer[] arr) {
return func.apply(arr);
}
If the method is void sendData(Integer data) that corresponds to a consumer that takes an Integer and returns a void which is covered by the built in Consumer<Integer> interface which has an accept(Integer) method that will invoke your function when called.
So your code will look like this:
public void init(Consumer<Integer> sendMethod) {
storedSendMethod = sendMethod;
// ...
}
// Plugin run
void run() {
// ...
storedSendMethod.accept(x) // Sends data to server
// ...
}
As a sidenote, having an init method is probably a bad Java design. you are better moving the initialization to the constructor if possbile
Plugin p = new PluginImplementation( this::sendData);
In java, you do it with a callback,
This is your callback interface,
public interface SendCallback {
public void doSend(Object toSend);
}
This is the plugin interface, All plugin must implement this interface
public interface Plugin extends Runnable {
public void init(SendCallback callback);
}
This is the Server's code.
public class Server {
Plugin plugin;
SendCallback callback = new SendCallback() {
public void doSend(Object toSend) {
// logic to send object 'toSend'
}
}
public Server() {
plugin = new MyPlugin();
plugin.init(callback);
}
}
This is your plugin implementation.
public class MyPlugin implements Plugin {
SendCallback callback = null;
Object x = null;
public void init(SendCallback callback) {
this.callback = callback;
}
public void run() {
x = "Somthing"; // initialize the x object
callback.doSend(x);
}
}
You will notice, the server define the callback implementation.
The plugin will invoke the callback's method doSend.
I hope, this helps
There is method reference in Java 8, however you can just pass a whole object and call its sendData() method. In a 'plug-in' situation, using interfaces for each helps the plugin and the server have 'looser' coupling.
public interface Server {
void setData(...);
}
public class MyPlugin implements plugin {
private Server server;
void init(Server s ) {
this.server = s;
}
void run() {
...
this.server.setData(...);
...
}
}
interface Server{
...
void sendData(String message);
}
Plugin doesn't need a function reference, you can use the Server interface for informing Plugin to know about that method.
class PluginX implements Plugin{
...
private Server server;
void init(Server server) {
this.server = server;
}
public void run() {
// ...
server.sendData(x) // Sends data to server
// ...
}
}

Categories