Statically providing metadata for a class in an enforceable manner - java

This is a little bit of a complicated issue, but I'll do my best to explain it understandably.
To start, consider the following classes.
public abstract class Invokable {
private String name;
protected Invokable(String name) { ... }
public String getName() { ... }
public abstract void invoke();
}
public class PrintInvokable extends Invokable {
public PrintInvokable() {
super("print");
}
#Override
public void invoke() { ... }
}
Another class, InvokerDispatcher, handles events from a messaging application and calls Invokable#invoke on an instance of the appropriate implementation based on the name field. This is all done reflectively so as to be able to scan the classpath for all the valid Invokable implementations and dynamically load them at runtime.
The issue here is that I can only access name via instance, so I have to instantiate a copy of every Invokable in order to check its name against the message content. My solution right now is to keep a list of pre-instantiated copies of each implementation in a separate class, then call a method that fetches and replaces an instance from the list by name.
I'd like to be able to access name statically instead, but I can't come up with a way to do so enforcably. Having a static abstract getName() in Invokable would be the easiest way to do it, but unfortunately Java doesn't support it. Any ideas?
My abstraction of this issue probably isn't the best, so here's my actual source code. The relevant classes are in the command package.

Related

How do I correctly generate a dynamic proxy class that's based on the right class?

I have an interface defined as follows:
public interface Cache {
}
Then an abstract class implementing the above:
public abstract class AbstractCache implements Cache {
}
Then a concrete class inheriting from above:
public class RealTimeCache extends AbstractCache {
}
Then another class defined as follows:
public class CacheProbe {
public static <T> T probe(T base) {
return (T) Proxy.newProxyInstance(
base.getClass().getClassLoader(),
new Class[]{Cache.class},
new MethodCountInvocationHandler(base) // I am not mentioning this class as it's irrelevant
);
}
}
I have a class as follows which is using all of the above:
public class CacheLoader<T extends Cache> {
public T load() {
T result = getResult(...);
CacheProbe x = new CacheProbe(result);
return x.probe();
}
}
Lastly, the lines causing the issue (located outside above classes):
final CacheLoader<RealTimeCache> cacheLoader = getNewLoader(); //Method of this method is irrelevant and unchangeable
RealTimeCache x = cacheLoader.load(); //This is the line which is causing a runtime issue
Problem is, at run time the following exception is thrown at the last line mentioned above:
java.lang.ClassCastException: com.sun.proxy.$Proxy57 cannot be cast to RealTimeCache
However I don't see how this is possible because the dynamic proxy class generated is based on Cache.
How do I fix this ?
Please note that I can only change CacheProbe class in order to fix this. Cache, AbstractCache, RealTimeCache, CacheLoader and those last two lines are unchangeable.
However I don't see how this is possible because the dynamic proxy class generated is based on Cache.
Yes, the docs for java.lang.reflect.Proxy say
Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods.
(emphasis added)
Thus, you cannot use Proxy to create (an instance of) a subclass of an arbitrary class of your choice.
How do I fix this ?
You can create an ordinary subclass of RealTimeCache, and return an instance of that. Proxy is meant primarily to serve for interfaces that are not known until runtime, and in that case the only way to interact with them anyway is the interface type. That's not your scenario.
If necessary, you can implement such a subclass in terms of a MethodCountInvocationHandler, just as your proxy class uses, but I'm sure it would be easier to implement whatever tooling that is supposed to provide directly.

Listening to class reload in Java

For performance reasons, I have a class that stores a Map whose key is a Class<?> and its value is function of that class's fields. The map is populated during code execution according to the type of the calling object. The above is a generalization/simplification
public class Cache {
private static final Map<Class<?>, String> fieldsList = ...;
//Synchronization omitted for brevity
public String getHqlFor(Class<?> entity){
if (!fieldsList.containsKey(entity))
fieldsList.put(entity,createHql(entity));
return fieldsList.get(entity);
}
}
During development, thanks to the help of Jrebel, I often make modifications to classes by changing entire properties or just their names. I can continue development just fine. However, if I already put a value into the cache it will be stale forever.
What I am asking here is if it is possible to intercept the event that a class in the classpath has changed. Very broad... But my specific problem is very simple: since I have such a need only during development, I just want to wipe that cache in case any class in my classpath changes.
How can I accomplish this? I don't need to do anything special than intercepting the event and simply wiping the cache
JRebel has a plugin API that you can use to trigger code on class reloads. The tutorial complete with example application and plugin available here: https://manuals.zeroturnaround.com/jrebel/advanced/custom.html
The JRebel plugin is a self-contained jar built against the JRebel SDK, which is attached to the running application via the JVM argument -Drebel.plugins=/path/to/my-plugin.jar. The JRebel agent attached to the application will load and start plugins from this argument.
If the application is not started with the JRebel agent, the plugin is simply not loaded.
In your example you want to register a ClassEventListener that will clear the Cache.fieldsList map. As it is a private field, you need to access it via reflection or add a get/clear method via a ClassBytecodeProcessor
public class MyPlugin implements Plugin {
void preinit() {
ReloaderFactory.getInstance().addClassReloadListener(new ClassEventListenerAdapter(0) {
#Override
public void onClassEvent(int eventType, Class<?> klass) throws Exception {
Cache.clear();
}
});
}
// ... other methods ...
}
And to clear the map
public class CacheCBP extends JavassistClassBytecodeProcessor {
public void process(ClassPool cp, ClassLoader cl, CtClass ctClass) {
ctClass.addMethod(CtMethod.make("public static void clear() { fieldsList.clear(); }", ctClass));
}
}
However a better option is to only clear/recalculate the single class entry on class reload if possible. The example didn't display whether the info computed from one class depended on superclass infos, but if this is true, the JRebel SDK has methods to register a reload listener on the class hierarchy as well.
There is an existing class ClassValue which already does the job for you:
public class Cache {
private final ClassValue<String> backend = new ClassValue<String>() {
#Override
protected String computeValue(Class<?> entity) {
return createHql(entity);
}
};
public String getHqlFor(Class<?> entity){
return backend.get(entity);
}
}
When you call get, it will call computeValue if this is the first call for this specific Class argument or return the already existing value otherwise. It does already care thread safety and for allowing classes to get garbage collected. You don’t need to know when class unloading actually happens.

Design pattern to use when you need to initialize your object?

I have a class, which has an Initialize method, which creates a bunch of tables in a database. This class looks like this:
public class MyClass
{
private bool initialized = false;
public void Initialize()
{
if(!initialized)
{
//Install Database tables
initialized = true;
}
}
public void DoSomething()
{
//Some code which depends on the database tables being created
}
public void DoSomethingElse()
{
//Some other code which depends on the database tables being created
}
}
The two methods DoSomething and DoSomethingElse need to make sure that the Initialize method has been called before proceeding because they depend on having the tables in the database. I have two choices:
Call the Initialize method in the constructor of the class - this does not seem like a good idea because constructors should now call methods, which are non-trivial and could cause an exception.
Call the Initialize method in each of the two methods - this does not seem like a great solution either especially if there are more than a handful of methods.
Is there a design pattern which could solve this in a more elegant way?
I would use a static factory method in which Initialize is invoked, and make the constructor private, to force use of the static factory method:
public class MyClass
{
private MyClass() { ... }
public static MyClass createInstance() {
MyClass instance = new MyClass();
instance.Initialize();
return instance;
}
}
Also, I would remove the initialized variable - in part because you don't need it any more - but also because it requires some means of guaranteeing visibility (e.g. synchronization, volatile or AtomicBoolean) for thread safety.
I think that Miško Hevery's blog post on (not) doing work in constructors is an interesting read.
I would separate the installation of the database from the definition of tasks that depends on it:
static factory could be used for the database installation as pointed out by #andy-turner
and the repository pattern to do work on the database
I suggest this solution because if i understand correctly, you are concerned about the high number of tasks that depends on the database.
Using the dependency injection pattern the repository can get a reference to the database, so in your bootstrapping code you can execute the database installation once and then inject the reference to the database in all the repositories that depends on it.
I would recommend using a collaborator that does the initialisation. That way MyClass can easily be tested by substituting a mock for the initialiser collaborator. For example:
public class MyClass {
public MyClass(MyClassInitialiser initialiser) {
initialiser.initialize();
}
public void DoSomething() {
//Some code which depends on the database tables being created
}
public void DoSomethingElse() {
//Some other code which depends on the database tables being created
}
}
Or an alternative solution, the idea here is that you're breaking the single responsibility principle in MyClass. There is non-trivial initialisation behaviour (installing database tables) and behaviour on those tables in the same class. So you should separate those responsibilities into two different classes and pass one in as a collaborator to the other.
public class MyClass {
DatabaseCollaborator collaborator;
public MyClass(DatabaseCollaborator collaborator) {
this.collaborator = collaborator;
}
public void DoSomething() {
//Some code which depends on the database tables being created
collaborator.someMethod();
}
public void DoSomethingElse() {
//Some other code which depends on the database tables being created
collaborator.anotherMethod();
}
}
public class DatabaseCollaborator {
DatabaseConfig config;
public DatabaseCollaborator(DatabaseConfig config) {
this.config = config;
}
public void someMethod() {
}
public void anotherMethod() {
}
}
public class DatabaseConfig {
public DatabaseConfig() {
// initialize
}
}
When I want a class whose instances must be initialized exactly once but I want to defer initialization until right before it's necessary (at which point the caller may fail to call an Initialize function, find it inconvenient to do so, or etc.), I do it similar to how you've started out with your code, but I make the initialization method private and name it something like "EnsureInitialized". It uses a flag to track and early exit if initialization has already been done, and all functions which depend on initialization already having happened just call that function as their first line (after argument-checking).
If I expect the caller to control when this instance's initialization is done, I make the method public, name it "Init", track whether it has been run with a flag, handle idempotence or max-run-once inside the Init method however is appropriate for that class, and all methods which depend on Init having already been run will call a different, private method named "AssertIsInitialized" which will throw an exception with text like "Must call init on {class name} instance before using this function".
My goal with these different patterns is to be unambiguous about each method's expectations and operation regarding initialization within the class instance lifecycle, and provide discoverability (of the design or code bugs using it) and automatic behavior (in the case of the self-initializing class in my first paragraph) wherever I think each is most appropriate to what the rest of the application is doing.

Is it possible to limit method execution to a certain class?

I was wondering if it was possible to only allow a certain set of classes to execute a function.
I have a method: setPermission()
This method should only be called by certain classes throughout the project.
Some people suggested having the calling class pass in this, referencing the current object and ensuring it is an instanceof an allowed class. But any class could pass in an instance of an allowed class an so this seems to be an poor solution.
I also stumbled across Exception().getStackTrace()[1].getClassName(); however I am led to believe this is quite an expensive operation.
Is there a correct way to do this?
Use a marker interface (one that doesn't have any methods):
public interface Permissible {}
Then have the classes that are allowed to call your method implement it, then change the parameter type of your method to this interface:
public static void myMethodForObjectsThatHavePermission(Permissible obj) {
//
}
There's no way to enforce it that can't be worked around, but you could have most of your functionality on one class, setPermission() on a subclass, and make clients get an instance of your class via a factory method that is declared to return the parent class, but actually returns an instance of the subclass. That way, code that is supposed to call setPermission(), and knows about it, can do a downcast and call it, and all other users of the class won't even see it.
public class Service {
protected boolean permission = false;
protected Service() {
/* control creation */
}
public static Service getService() {
return new RealService();
}
public void doStuff() {
/* the public API side of the service */
}
}
public class RealService extends Service {
protected RealService() {
/* control creation */
}
public void setPermission(boolean permission) {
this.permission = permission;
}
}
A legitimate caller can do this:
public class Legitimate {
public void method() {
Service service = Service.getService();
RealService real = (RealService) service;
real.setPermission(true);
}
}
However, if all the legitimate callers can be put into the same package, and all the rest are outside the package, then package-private access (no access modifier) for setPermission() would be sufficient.
This doesn't prevent malicious callers from getting around the restriction, but it does avoid people calling setPermission without realizing they're not supposed to, because setPermission wouldn't show up in autocompletion (intellisense) in an IDE.
Sounds to me like you're looking for OSGi (en.wikipedia.org/wiki/OSGi). Third party developers should write bundles and with OSGi you can restrict capabilities of their bundles. Put your attention to: "Security The layer that handles the security aspects by limiting bundle functionality to pre-defined capabilities." Here is a thread discussing your case: Managing access to OSGI bundles

Java Class scope and library

I am creating a Java library, as a final product in intend to distribute this .jar to developers.
I am "translating" my library from Objective-C where I control which classes header files are available to the developer. In other words I am only exposing to the developer a few classes they can handle.
In my Java library I am using packages and my package has grown quite big. So I decided to separate into different packages my models and controllers. But now the models I wanted to keep private I need to mark as public in order to use from the main package.
My question is does this go against what I was doing in Objective-C ?
For example I have an Event class which is really only used internally and I don't want the user to know about it or think about it. I have another class TimedEvent, which the user can get an instance of an manage.
In my Objective-C, I simply excluded Event class from the library public scope, allowing TimedEvent.
If I am making things more tidy in my library then it seems packages aren't the way. Since now, my main controller is in the main package and all the models are in another package - forced to have a public scope.
Opinions ?
This is possible with Java but there are reasons why (almost) no one does it...
If you put the implementation and the interface into the same package, then you can omit all access modifiers (private, protected, public) from classes and methods to give them "default" or "package" visibility: Only classes in the same package are allowed to see/use them.
Drawback: You'll have to mix API and implementation.
The other approach is to move the implementation into a package *.private.*. No more mixing of API and implementation but malicious users can easily access the implementation - it's just a naming convention. Like a STOP sign: It means something ("be careful") but doesn't actually stop you.
Lastly, you can implement the interface inside of the interface. For example:
public interface IFoo {
String getName();
private static class Foo implements IFoo {
public String getName();
}
public static class FooFactory {
public static IFoo create() { return new Foo(); }
}
}
Ugly, ain't it?
The common approach to controlling exposure of your classes to the world is hiding implementations behind interfaces and factories.
Create an interface for your TimedEvent, and a class for creating instances of TimedEvent interface
Put the interface in the main package, and the factory in a sub-package
Give the factory public visibility
Implement the interface in the sub-package, giving it package visibility
Create an instance of the class implementing the TimedEvent interface in the factory
Here is an example of how you can do it:
package com.my.main;
public interface TimedEvent {
void fire();
}
package com.my.main.events;
import com.my.main;
public class EventFactory {
public TimedEvent makeTimedEvent() { return new TimedEvent (); }
}
// TimedEventImpl has package visibility - it is not public.
class TimedEventImpl implements TimedEvent {
public void fire() {
// Fire a timed event
}
}
The users would access TimedEvent like this:
com.my.main.events.EventFactory f = new com.my.main.events.EventFactory();
com.my.main.TimedEvent evt = f.makeTimedEvent();
evt.fire();

Categories