Enforce method call to avoid throwing exception - java

I have a library and to create an instance, I use the connectWith() method to send database model:
Wallet wallet = new WalletPoket();
wallet.connectWith(
DAOFactory.getDAOFactory(DAOFactory.MYSQL)
);
Followed by these methods:
int privateCardId = wallet.addCard(1, "Economy 1");
boolean wasDeleted = wallet.deleteCard(privateCardId);
...
Calling the previous methods will result in a NullPointerException if the connectWith() method is not called prior.
Is it possible to force the user to call the connectWith() method or present the user with a warning if they do not?
Would it be acceptable to call the method from the constructor?
Wallet wallet = new WalletPoket(
DAOFactory.getDAOFactory(DAOFactory.MYSQL)
);
What would be the best alternative?

You have a few options.
Force the user to pass the option as an argument to the constructor.
Throw an exception with a message stating that connectWidth must be called if it was not called.
If there is a good default thing to connect with, then connect with that in the constructor.

This is where things get a bit verbose, since it means:
You have to check state before you do anything, and
You have to guard against developers doing silly things.
One thing you can do is check the state of your connection (ensuring that it's not null), then throwing an IllegalStateException explaining why it blew up:
if(null == daoFactory) {
throw new IllegalStateException("You are attempting to invoke this without a DAO Factory defined.");
}
...but you'd have to add this check to every method that you had in your program.
A preferred approach in my mind would be to add this to the constructor of the object, since that clearly captures the need to have this dependency before the entity is constructed. So effectively, I agree with your second approach.
The last thing you could do is do some fancy annotation processing to force a specific compiler warning or error should this dependency go missing, but it's likely a lot more straightforward to add it in as a constructor dependency instead.

If the addCard and deleteCard method calls are crucial to the Object's functionality (i.e almost always called), then add it as a constructor.
Otherwise, you can simply throw a detailed IllegalStateException when they're called in the wrong order. You should also document the library methods accordingly explaining what's needed for them to function properly.

The (library) class Wallet should have provided a constructor that takes the database endpoint. Since it is not available, you could provide a utility wrapper that accounts for it. That way, your utility wrapper can mandate the endpoint and make sure that it is available beforehand.
Another thing you can explore is dependency injection, i.e. whenever a client needs a Wallet, it does #Inject Wallet wallet. This, admittedly, has added complexity, but it renders the code that is more easily testable. (See javax.inject, or dagger).

I think, you should implement proxy design pattern to solve the problem.
When the client creates a Wallet, they should get the proxy of the Wallet instance.When client invokes the service API say addCard then Real Wallet object instance comes into picture(lazy loading) and does the dao instantiation which is a singleton instance.

Related

Know what class instantiated a class

Basically, I'm creating an API. I have multiple endpoints, implemented as controllers. If an endpoint is called, it instantiates a parserclass, adds some options (like permitted parameters etc).
But now: If the parser fails, I want it to present a nice error, containing a link to the docs of the endpoint that actually failed.
I use b4j, which works on top of Java, so any relevant Java code should be easy to convert. In b4j, any endpoint is resembled by a class.
E.g.
I have a 'getPOIByCity' endpoint.
If a user calls this method, a city parameter is required. If he/she omits the parameter, I want the user to be greeted with an error containing:
1 required parameter missing: city
See the documentation: http://www.link.to/doc/getPOIByCity
My first thought was to do some kind of stack tracing to know which class instantiated the parses class, but I cannot believe that is the way to do this.
C# has the slightly more elegant 'Caller information' attributes.
Any insights in how to do this?
As another-dave already mentioned, it would make a lot more sense to delegate the exception to the calling class (the controller) and show the error from there.
But just to give an answer to your problem, you can use
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
String parentClass = stackTraceElements[2].getClassName();
Class cl = Class.forName(parentClass);
to achieve what you want.

What exception to use to prevent a method from being called multiple times?

I have a method that should only be called once during an object's lifetime. In order to ensure that this is the case, the method sets a boolean flag in the Object to true so it can later check if this method has already run. I am currently throwing an IllegalArgumentException (with a descriptive message) if this method is called a second time during a single object's lifetime, but that doesn't feel quite right to me, since the problem is not actually with the arguments themselves. Is there a better exception to use than an IllegalArgumentException?
I chose not to use an assert statement in this case, because the class and method are both visible outside the package, so the problem may be caused by code outside of my package. Is that correct thinking?
Throw an IllegalStateException.
But since exceptions shouldn't be part of the ordinary control flow, you should add a companion method, which returns a boolean that indicates whether the next call to the method will be successful.
An example for such a companion method is Iterator#hasNext().
A well-designed API must not force its clients to use exceptions for
ordinary control flow. A class with a “state-dependent” method that
can be invoked only under certain unpredictable conditions should
generally have a separate “state-testing” method indicating whether it
is appropriate to invoke the state-dependent method. For example, the
Iterator interface has the state-dependent method next and the
corresponding state-testing method hasNext.1
1: from Effective Java, Chapter 9: Exceptions
What should worry you more than the specific exception type is the fact that you created a bad design here.
Good interfaces make it easy to do the right thing and hard to do the wrong thing.
Meaning: your current implementation makes it easy to call that method twice; respectively you now force your clients to always check if that method was already called.
So, instead of spending your time on the exception type: step back and figure how to dissect your one class into two classes for example. And find a nice so that calling that specific method gives you a different object to work on. Or check if you should rather use a state machine to solve this problem.

Java - Creating a class to dynamically determine if user has access to the calling method

I have tried doing a search for this but I fear I may not be wording what I want to do very well.
Currently, we have about a hundred action classes in our application with each determining if a user has access to it. I would like to make a class that can figure out the calling method, what permissions are required for it, and if the user has those permissions. Unfortunately, I don't really know how to even get started with this as each class may have slightly different requirements.
I'm happy to add more explanation if needed but as I said, I'm not sure I'm wording what I'm trying to do very well so if anyone has a better way of putting it that gets me some google results or a link to a related question here that's already been answered, I know I'd appreciate it.
current permissions checks look like below. This is a simple implementation, there are usually multiple profile checks in one if block.
If (scc.getUser().getCurrentProfile().getSystemAdmin() != 1) {
logIllegalAccess(log);
break;
}
IMHO the most elegant solution would make use of annotation processing. The idea is that you would annotate action classes with a custom annotation, something like:
#RequiredPermission(Permissions.SYSADM)
class ActionA {
public ActionA newInstance() {
return new ActionA_Gen(new ActionA());
}
private ActionA() {...}
...
}
Action classes would have to have a newInstance() method to be used to create instances instead of calling new. The method would create an instance of a class by the same name with _Gen extension. This class would have one method for each method in the original action class, which would perform a permission check and call the corresponding method in the original class instance that was passed to its constructor.
The _Gen class would be generated by an annotation processor.
Note that by using reflection it might be possible to move the newInstance() method in a common superclass.

How to prevent client from seeing internal private classes in Android library ?

I have a library with several packages-
lets say
package a;
package b;
inside package a I have public a_class
inside package b I have public b_class
a_class uses b_class.
I need to generate a library from this , but I do not want the Client to see b_class.
The only solution I know of is to flatten my beautifully understandable packages to single package and to use default package access for b_class.
Is there another way to do so ? maybe using interfaces or some form of design pattern ??
If you reject to move the code to an individual, controlled server, all you can do is to hinder the client programmer when trying to use your APIs. Let's begin applying good practices to your design:
Let your packages organized as they are now.
For every class you want to "hide":
Make it non-public.
Extract its public API to a new, public interface:
public interface MyInterface {...}
Create a public factory class to get an object of that interface type.
public class MyFactory
{
public MyInterface createObject();
}
So far, you have now your packages loosely coupled, and the implementation classes are now private (as good practices preach, and you already said). Still, they are yet available through the interfaces and factories.
So, how can you avoid that "stranger" clients execute your private APIs? What comes next is a creative, a little complicated, yet valid solution, based on hindering the client programmers:
Modify your factory classes: Add to every factory method a new parameter:
public class MyFactory
{
public MyInterface createObject(Macguffin parameter);
}
So, what is Macguffin? It is a new interface you must define in your application, with at least one method:
public interface Macguffin
{
public String dummyMethod();
}
But do not provide any usable implementation of this interface. In every place of your code you need to provide a Macguffin object, create it through an anonymous class:
MyFactory.getObject(new Macguffin(){
public String dummyMethod(){
return "x";
}
});
Or, even more advanced, through a dynamic proxy object, so no ".class" file of this implementation would be found even if the client programmer dares to decompile the code.
What do you get from this? Basically is to dissuade the programmer from using a factory which requires an unknown, undocumented, ununderstandable object. The factory classes should just care not to receive a null object, and to invoke the dummy method and check the return value it is not null either (or, if you want a higher security level, add an undocumented secret-key-rule).
So this solution relies upon a subtle obfuscation of your API, to discourage the client programmer to use it directly. The more obscure the names of the Macguffin interface and its methods, the better.
I need to generate a library from this , but I do not want the Client to see b_class. The only solution I know of is to flatten my beautifully understandable packages to single package and to use default package access for b_class. Is there another way to do so ?
Yes, make b_class package-private (default access) and instantiate it via reflection for use in a_class.
Since you know the full class name, reflectively load the class:
Class<?> clz = Class.forName("b.b_class")
Find the constructor you want to invoke:
Constructor<?> con = clz.getDeclaredConstructor();
Allow yourself to invoke the constructor by making it accessible:
con.setAccessible(true);
Invoke the constructor to obtain your b_class instance:
Object o = con.newInstance();
Hurrah, now you have an instance of b_class. However, you can't call b_class's methods on an instance of Object, so you have two options:
Use reflection to invoke b_class's methods (not much fun, but easy enough and may be ok if you only have a few methods with few parameters).
Have b_class implement an interface that you don't mind the client seeing and cast your instance of b_class to that interface (reading between the lines I suspect you may already have such an interface?).
You'll definitely want to go with option 2 to minimise your pain unless it gets you back to square one again (polluting the namespace with types you don't want to expose the client to).
For full disclosure, two notes:
1) There is a (small) overhead to using reflection vs direct instantiation and invocation. If you cast to an interface you'll only pay the cost of reflection on the instantiation. In any case it likely isn't a problem unless you make hundreds of thousands of invocations in a tight loop.
2) There is nothing to stop a determined client from finding out the class name and doing the same thing, but if I understand your motivation correctly you just want expose a clean API, so this isn't really a worry.
When using Kotlin, you can use the internal modifier for your library classes.
If I understand correctly you are asking about publishing your library for 3rd party usage without disclosing part of your source? If that's the case you can use proguard, which can obfuscate your library. By default everything will be excluded/obfuscated, unless you specify things you want to exclude from being obfuscated/excluded.
If you want to distribute [part of] your code without the client being able to access it at all, that means that the client won't be able to execute it either. :-O
Thus, you just have one option: Put the sensible part of your code into a public server and distribute a proxy to access it, so that your code would be kept and executed into your server and the client would still be able to execute it through the proxy but without accessing it directly.
You might use a servlet, a webservice, a RMI object, or a simple TCP server, depending on the complexity level of your code.
This is the safest approach I can think of, but it also deserves a price to pay: In addition to complexing your system, it would introduce a network delay for each remote operation, which might be big deal depending on the performance requirements. Also, you should securize the server itself, to avoid hacker intrussions. This could be a good solution if you already have a server that you could take advantage of.

overwrite a method in a jdbc third party jar

I want to access my database through ebean. My database is a Gupta SQLBase 11.5 (don't wonder if you don't know it). The problem is that the guys at gupta are very lazy. So their implementation of java.sql.DatabaseMetaData.getDatabaseMajorVersion throws an SqlException: unsupported method. Is it possible to overwrite that method in my application so that it just returns 11? I already tried to implement my own jdbc.gupta.sqlbase.SqlbaseDatabaseMetaData class with this method which indeed works but I'm not able to implement all methods the interface needs. That is why all selects I do through ebean returns null. So I only need to overwrite the getDatabaseMajorVersion method. IMHO there is no opinion to implement a subclass which just extends the gupta class cause my class would never be taken.
thanks for every advise you can give.
best regards, Marco
You can write a wrapper, either by using the delegate pattern, or by Proxy (reflection). You will need to intercept any invocation of the "overriden" methods, and delegate the others to the underlying object.
For convenience, you could also write a wrapper for Connection, and override Connection.getMetaData(), which should return an instance of your wrapper.
If you want to go fancy, you may also register an implementation of Driver that rewrites the connection URL and returns an instance of your Connection.

Categories

Resources