I came into this whilst spending my night programming.
//Reader class isn't java.io but it's from third party library
public class ACR122U extends Reader {
// This method is called from outside
// This method overrides method of the Reader class
#Override
public void open(UsbDevice device) {
new OpenTask().execute(device);
}
private class OpenTask extends AsyncTask<UsbDevice, Void, Exception> {
#Override
protected Exception doInBackground(UsbDevice... params) {
Exception result = null;
try {
// There the problem (recursion) happens
// I don't want to call ACR122U.open() but Reader.open()
// I cannot call super.open() /super of OpenTask class is AsyncTask/
open(params[0]);
} catch (Exception e) {
result = e;
}
return result;
}
}
}
and I'm wondering if it's possible to solve the problem without changing name of open() method.
Any idea?
PS: Newbie here.
The syntax for what you want to do is:
ACR122U.super.open(params[0]);
However, if you're talking about java.io.Reader, this isn't going to work because the Reader class doesn't define an open() method; certainly not an open(UsbDevice) method.
Related
Is there a way to always execute a function before any other function of a class is called?
I have a class where I need to refresh some fields always before any function is called:
public class Example {
private int data;
public void function1(){
}
public void function2(){
}
//#BeforeOtherFunction
private void refresh(){
// refresh data
}
}
Because it seems to be bad programming, I don't want to call refresh at the beginning of every other function. Since other persons are going to work on this project as well, there would be the danger, that somebody extends the calls and doesn't call refresh.
JUnit has a solution for this with the #Before-Annotation. Is there a way to do this in other classes as well?
And by the way: If you know a programming pattern wich solves this problem in another way than executing a function everytime any function is called, that would be very helpful, too!
Use a dynamic proxy in which you can filter to those methods before which your specific "before" method should be called. And call it in those cases before dispatching the call. Please see the answer from How do I intercept a method invocation with standard java features (no AspectJ etc)?
UPDATE:
An interface is needed to be separated for the proxy. The refresh() method cannot remain private. It must be public and part of the interface (which is not nice here) to be able to be called from the proxy.
package CallBefore;
public interface ExampleInterface {
void function1();
void function2();
void otherFunction();
void refresh();
}
Your class implements that interface:
package CallBefore;
public class Example implements ExampleInterface {
#Override
public void function1() {
System.out.println("function1() has been called");
}
#Override
public void function2() {
System.out.println("function2() has been called");
}
#Override
public void otherFunction() {
System.out.println("otherFunction() has been called");
}
#Override
public void refresh() {
System.out.println("refresh() has been called");
}
}
The proxy which does the trick. It filters the needed methods and calls refresh().
package CallBefore;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ExampleProxy implements InvocationHandler {
private ExampleInterface obj;
public static ExampleInterface newInstance(ExampleInterface obj) {
return (ExampleInterface) java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), new ExampleProxy(obj));
}
private ExampleProxy(ExampleInterface obj) {
this.obj = obj;
}
#Override
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Object result;
try {
if (m.getName().startsWith("function")) {
obj.refresh();
}
result = m.invoke(obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
}
return result;
}
}
The usage:
package CallBefore;
public class Main {
public static void main(String[] args) {
ExampleInterface proxy = ExampleProxy.newInstance(new Example());
proxy.function1();
proxy.function2();
proxy.otherFunction();
proxy.refresh();
}
}
Output:
refresh() has been called
function1() has been called
refresh() has been called
function2() has been called
otherFunction() has been called
refresh() has been called
This may not solve your exact problem but at least could be a starting point if you are allowed considering a re-design. Below is a simple implementation but with some small touches I believe you can achieve a more elegant solution. BTW, this is called Dynamic Proxy Pattern.
First thing you need is an interface for your class.
public interface Interface {
void hello(String name);
void bye(String name);
}
public class Implementation implements Interface {
#Override
public void hello(String name) {
System.out.println("Hello " + name);
}
#Override
public void bye(String name) {
System.out.println("Bye " + name);
}
}
Then java.lang.reflect.Proxy class comes to help. This class is able to create an instance for a given interface at runtime. It also accepts an InvocationHandler which helps you to capture method calls and looks like this.
public class InvocationHandlerImpl implements InvocationHandler {
private final Object instance;
public InvocationHandlerImpl(Object instance) {
this.instance = instance;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
try {
System.out.println("Before");
result = method.invoke(instance, args);
System.out.println("After");
} catch (Exception e){
e.printStackTrace();
throw e;
} finally {
System.out.println("finally");
}
return result;
}
}
After all your client code will look like this.
Interface instance = new Implementation();
Interface proxy = (Interface)Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[] { Interface.class },
new InvocationHandlerImpl(instance));
proxy.hello("Mehmet");
proxy.bye("Mehmet");
Output for this code is
Before
Hello Mehmet
After
finally
Before
Bye Mehmet
After
finally
I would define getters for every field and do the refreshment inside the getter. If you want to avoid unrefreshed access to your private fields at all, put them in a superclass (together with the getters which call refresh).
Depending on your project structure, it may be also sensible to introduce a separate class for all data that is regularly refreshed. It can offer getters and avoid that anyone accesses the non-refreshed fields.
Not in Java SE, but if you are using Java EE, you could use interceptors.
For standalone applications, you could consider using a bytecode manipulation framework, like javassist.
You can have a protected getter method for data. Access getData method instead of using data field. Child classes will see only getData and will have updated data every time.
public class Example {
private int data;
public void function1(){
}
public void function2(){
}
protected int getData(){
refresh();
return data;
}
//#BeforeOtherFunction
private void refresh(){
// refresh data
}
}
It is better to write another method which will be made protected(accessible to the child classes) which will call first the refresh method and then call the function.
This way the data would be refreshed before the function is called everytime(As per your requirement).
eg:
protected void callFunction1(){
refresh();
function();
}
Thanks,
Rajesh
You should use Decorator in this case. Decorator is a good choice for something like interceptor. Example here: https://msdn.microsoft.com/en-us/library/dn178467(v=pandp.30).aspx
Is there any good way of using try-with-resources when opening an InputStream in a constructor and then passing that to a super constructor?
Basically what I want to do is this:
public class A {
public A(InputStream stream) {
// Do something with the stream but don't close it since we didn't open it
}
}
public class B {
public B(File file) {
// We open the stream so we need to ensure it's properly closed
try (FileInputStream stream = new FileInputStream(file)) {
super(new FileInputStream(file));
}
}
}
But, of course, since super must be the first statement in the constructor this isn't allowed. Is there any good way of achieving this?
Consider using a static factory method instead of using the constructor directly. Make at least B's constructor private, and create a method such as
private B(InputStream is) {
super(is);
// Whatever else is needed
}
public static B newInstance(File file) {
B result;
try (FileInputStream stream = new FileInputStream(file)) {
result = new B(stream);
}
// Further processing
return result;
}
Another way to go :
public class A {
protected A(){
// so he can't be called from the outside, subclass ensure that init is done properly.
}
public A(InputStream stream) {
init(stream);
}
// not be able to call it from outside
protected final init(InputStream is){
//here goes the code
}
}
public class B {
public B(File file) {
// We open the stream so we need to ensure it's properly closed
try (FileInputStream stream = new FileInputStream(file)) {
init(stream);
}
}
}
I'm posting this here as a possible answer, however here i'm consdering :
You can update A's code
You're moving constructor's code to an init method, thanks to protected empty arg constructor, only subclasses have to handle the call to init properly. Some may see that as not so well designed. My point is as soon your subclassing something, you have to know more about it that just when you just using it.
Sadly I do not have a compiler on hand to test on but could you not do as follows.
public class B {
private static InputStream file2stream(File f){
// We open the stream so we need to ensure it's properly closed
try (FileInputStream stream = new FileInputStream(file)) {
return stream;
}catch(/*what you need to catch*/){
//cleanup
// possibly throw runtime exception
}
}
public B(File file) {
super(file2stream(file))
}
}
I am trying to refactor the below code
class FileDownloadResource{
#Inject
private FileDownload fileDownload;
#Path(/abc)
public Response downloadFileABC(){
try{
fileDownload.downloadABC();
}catch(IOException e){
}
//Some code here that is common to the second method as well
}
#Path(/xyz)
public Response downloadFileXYZ(){
try{
fileDownload.downloadXYZ();
}catch(IOException e){
//handle exception
}
//Some code here that is common to the first method as well
}
}
The class is a JAX-RS rest resource. As you can see in the above code, everything except what is in the try block is the same for two method. Can we use any of the new JDK 8
features to pass fileDownload.downloadABC() as an argument to a private method ?
Basically, I am looking for some way to pass a function
as an argument and let the other part of the code be same.
Sure you can. You need either to use existing functional interface or create the new one. As you expect checked IOException, it's better to create the new one (you could also use Callable<Void>, but it's less convenient):
#FunctionalInterface
interface IORunnable {
void run() throws IOException;
}
Now you can create generic request handler private method:
public Response handleRequest(IORunnable r){
try {
r.run();
} catch(IOException e){
// handle exception
}
//Common code follows
}
And use it like this:
#Path("/abc")
public Response downloadFileABC(){
return handleRequest(fileDownload::downloadABC);
}
Or with lambda:
#Path("/abc")
public Response downloadFileABC(){
return handleRequest(() -> fileDownload.downloadABC());
}
You can do this, as long as the downloadABC() and downloadXYZ() methods have the same parameters and return value as the download() method of the Download interface.
Name of interface and interface method can be anything you choose.
#FunctionalInterface
interface DownloadMethod {
public void doDownload() throws IOException;
}
class FileDownload {
public void downloadABC() throws IOException {}
public void downloadXYZ() throws IOException {}
}
class FileDownloadResource{
#Inject
private FileDownload fileDownload;
#Path("/abc")
public Response downloadFileABC(){
return download(fileDownload::downloadABC);
}
#Path("/xyz")
public Response downloadFileXYZ() {
return download(fileDownload::downloadXYZ);
}
private Response download(DownloadMethod method){
try{
method.doDownload();
}catch(IOException e){
//handle exception
}
//Some code here that is common to both methods
}
}
I have created an generic AsyncTask class, so that I can catch all Exceptions thrown when task method is executed:
public abstract class Poc<ParamType, ReturnType>
extends AsyncTask<ParamType, String, ReturnType> {
abstract ReturnType task(ParamType... param);
#Override
protected ReturnType doInBackground(ParamType... param) {
try {
return task(param);
} catch (Exception e) {
// Make some Toast display the exception.
}
return null;
}
}
I try to implement the above class by doing some thing like:
public class Use {
public static void runIt() {
new Poc<String, Boolean>() {
#Override
Boolean task(String... param) {
return SomeObject.someMethodThatCanThrowAnException(param);
}
}.execute("Some String");
}
}
However, it keeps complaining about wanting me to add try/catch statements. Even when I know that task will only be called from doInBackground which wraps it.
Can I somehow suppress this? Or what is the proper approach without having to add try/catch to every single class that subclasses Poc?
As the compiler is trying to tell you, you need to declare your function as being able to throw things using throws Exception.
In this case, you would want the abstract method to be able to throw.
So I have two classes. One is abstract:
public abstract class AbstractClient {
protected boolean running = true;
protected void run() {
Scanner scanner = new Scanner(System.in);
displayOptions();
while (running) {
String input = null;
while (scanner.hasNext()) {
input = scanner.next();
}
processInputCommand(input);
}
}
abstract void displayOptions();
abstract void processInputCommand(String input);
}
One is the concrete subclass:
public class BasicClient extends AbstractClient {
private IBasicServer basicServer;
public static void main(String[] args) {
new BasicClient();
}
public BasicClient() {
try {
System.setSecurityManager(new RMISecurityManager());
Registry registry = LocateRegistry.getRegistry();
basicServer = (IBasicServer) registry.lookup(IBasicServer.LOOKUPNAME);
run();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
void displayOptions() {
BasicClientOptions.displayOptions();
}
#Override
void processInputCommand(String input) {
// TODO Auto-generated method stub
}
}
Now in the subclass I call the run() method of the abstract class because this should be common to all clients. Inside the run() method is a call to the abstract method displayOptions().
I have overridden displayOptions() in the subclass so I assumed that it would invoke the subclassed method but it seems it has not. Is there a way to do this or have I made an obvious mistake or have I misunderstood how abstract classes should work?
P.S I tried putting a print statement inside the subclassed displayOptions() to ensure I hadn't done something daft with method I call.
Many thanks,
Adam
Maybe something is wrong with your BasicClientOptions.displayOptions() call. I'm wondering how you know that BasicClient.displayOptions() isn't being called.
Here's a simplified version of what you have. Try running it. It behaves in the way you expect.
public abstract class BaseClass {
public void run() { foo(); }
public abstract void foo();
}
public class Subclass extends BaseClass {
public static void main(String[] args) { new Subclass().run(); }
#Override
public void foo() {
System.out.println("I'm from the subclass");
}
}
Is it the case that the classes are in different packages? If so you need to declare the method to override as protected.
Edit: (guess an explanation might help :-)
If you declare a method public/protected then it can be overridden by children outside of the package. If you make it (package)/private then it cannot. private methods cannot be overridden at all which (package) ones can only be overridden by classes in the same package.
I use (package) because there is no keyword for it, so in the absence of public/protected/private you get (package) access.
Edit:
The above is likely not true given your description (assuming that the class really is abstract, and you have used the #Override annotation).
Are you 100% sure that the run method is getting called? Put a System.out.println in run and make sure it is called.
Are you 100% sure that you are not catching any other exceptions and failing to print out the stack trace (or something else that will ensure that you see that the exception was caught)?
Not sure what the problem is, could you print some output (with your print statements).
I copy / pasted your code and aside from commenting out a line or two where I did'nt have the proper source for the object. It called the subclasses methods for me.
Logically, reading your code nothing seemed out of place but I prefer to see stuff with my own eyes to make sure there wasn't another issues and so I tried running your code first. :)
Here's what I modified and my output.
import java.util.Scanner;
public abstract class AbstractClient {
protected boolean running = true;
protected void run() {
Scanner scanner = new Scanner( "foo\\r\\nbar\\r\\n" );
displayOptions();
while ( running ) {
String input = null;
while ( scanner.hasNext() ) {
input = scanner.next();
}
processInputCommand( input );
running = false;
}
}
abstract void displayOptions();
abstract void processInputCommand( String input );
}
import java.rmi.RMISecurityManager;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class BasicClient extends AbstractClient {
//private IBasicServer basicServer;
public static void main( String[] args ) {
new BasicClient();
}
public BasicClient() {
try {
System.setSecurityManager( new RMISecurityManager() );
Registry registry = LocateRegistry.getRegistry();
//basicServer = (IBasicServer) registry.lookup(IBasicServer.LOOKUPNAME);
run();
} catch ( Exception e ) {
e.printStackTrace();
}
}
#Override
void displayOptions() {
//BasicClientOptions.displayOptions();
System.out.println( "We're in subclasses displayOptions()." );
}
#Override
void processInputCommand( String input ) {
System.out.println( "We're in subclasses processInputCommand()." );
}
}
My Output
We're in subclasses displayOptions().
We're in subclasses processInputCommand().
So in effect it seems your class was working just maybe the logging wasn't up to par.
Hope this helps.
This thread has been quiet for a while, so I doubt this will help you, but I thought I'd post it in case somebody else comes looking for answers.
Up until a few minutes ago, I was having a similar problem with an interface, abstract class, and concrete subclass. Basically the interface defines 10 methods, the abstract class implements 2 of those and leaves the other 8 for the concrete class. The implementation for one of the methods in the abstract class calls a method that was meant to be implemented by the concrete class.
Everything compiled fine and NetBeans didn't complain about anything but at runtime the VM bombed out, stating that the method (the one implemented in the concrete class) did not exist. It's been years since the last time I used Java, but I'm pretty sure this isn't the expected behavior in this situation (somebody please correct me if I'm wrong).
After several hours of kicking my laptop, I discovered that adding an abstract stub of the method I was calling to the abstract class allowed the call to be forwarded to the concrete class without any complaints from the VM. Is this normal or did I just get lucky?
Anyway, hope somebody finds this useful.