I have to maintain a code to add more flexibility to a final static variable in a class.
The variable is no more a global constant and may be changed.
The problem is that the class is in a common library and used in different projects.
Do you have an approach or a design pattern better than copying and pasting the class code from the common library to my specific application and refactoring it?
Example:
Commons project
Class CommonClass {
public final static var globalSomething = somethingGlobal;
public static method(){ //CommonClass.globalSomething is used here}
}
In my App (and other apps that reference commons) we can use the static attribute and also call the method:
---> var b = CommonClass.somethingGlobal;
---> var c = CommonClass.method() //we know that CommonClass.globalSomething is used here
Expectations:
Ability to change CommonClass.somethingGlobal in my app and take these changes in call CommonClass.method()
I can modify (add methods) in the common class but i have to keep the same initial behavior (not to break other project referencing common project)
If I got you right, you want to implement this as a parameter.
Looking at your example:
var c = CommonClass.method() //we know that CommonClass.globalSomething is used here
there is already something wrong with it. You shouldn't have to know that you have to set CommonClass.somethingGlobal correctly before calling the method. This way the client has to know the implementation, violating the principle of information hiding. If the value is required, introduce it as parameter:
Class CommonClass {
public static void method(var globalSomething){}
}
An alternative would be making both your variable and your method non-static and use a constructor:
Class CommonClass {
public var globalSomething = somethingGlobal;
public CommonClass(var globalSomething) {
this.globalSomething = globalSomething;
}
public void method(){}
}
PS: Your example code is not java. I corrected it partially in my answer.
Related
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.
I was hoping for someone to explain this item since I might be getting this wrong:
I was reading about Java Agent Instrumentation which says that the agent can start after VM startup. So if I want to dynamically replace some class (without brining down the app) is this what I am going to go for using agent-main? Or do I need to do something more here?
I know people might ask "Are you talking about JRebel" - not really because I want to do something simple and JRebel is an overkill.
instrument docs - Java docs for Instrumentation
I understand all the instrumentation overrides, but I am slightly confused how I can hook this agent with -agent argument after the app has started.
First your agent class needs to specify an agentmain method like:
public class MyAgent {
public static void agentmain(final String args, final Instrumentation inst) {
try {
System.out.println("Agent loaded.");
} catch (Exception e) {
// Catch and handle every exception as they would
// otherwise be ignored in an agentmain method
e.printStackTrace();
}
}
}
Compile it and pack it inside a jar-file for example. If you choose the jar-variant then it must specify the Agent-Class key in its manifest-file (MANIFEST.MF). It points to the class implementing the agentmain method. It could look like:
Manifest-Version: 1.0
Agent-Class: package1.package2.MyAgent
If it is located inside those packages, as an example.
After that you can load the agent via the VirtualMachine#loadAgent method (documentation). Note that the mechanism used by those classes are part of the Attach library of Java. They decided, as most users don't need it, to not directly add it to the systems path but you can just add it. It is located at
pathToYourJDKInstallation\jre\bin\attach.dll
And it needs to be somewhere where the system property java.library.path is pointing at. You could for example just copy it to your .../Windows/System32 folder or adjust the property or stuff like that.
As an example, if you want to inject an agent-jar inside another currently running jar, you could use a method like this:
public void injectJarIntoJar(final String processIdOfTargetJar,
final String pathToAgentJar, final String[] argumentsToPass) {
try {
final VirtualMachine vm = VirtualMachine.attach(processIdOfTargetJar);
vm.loadAgent(pathToAgentJar, argumentsToPass.toString());
vm.detach();
} catch (AttachNotSupportedException | AgentLoadException
| AgentInitializationException | IOException e) {
System.err.println("Unable to inject jar into target jar.");
}
}
With the same technique you can inject dll-libraries (if they implement the corresponding agent-methods via the native agent interface) into jars.
Actually, if that helps you, I have written some small library for that kind of stuff some time ago. See Mem-Eater-Bug, the corresponding class is Injector.java and the whole project has a small Wiki.
It has an example showing how to use that technique to manipulate a SpaceInvaders game written as Java application.
So apparently you want to reload classes at runtime. Such that your project can react to changes of the code without restarting.
To achieve this you need to prepare your project and write a very clean architecture, it involves using interfaces, factory-patterns, proxy-patterns and a routine that checks for updates and then destroys and rebuilds all current objects.
Unfortunately this might not be an easy task, but it is doable, depending on the size of your project and the amount of code that should react dynamically to changes.
I found this article helpful, let me explain how it works. You can easily load a class with ClassLoader.loadClass(...) and you can also use that to reload a class, very easy. However at the time you have compiled your code classes are some kind of hardwired already. So your old code will continue to create instances of the old classes although you have reloaded the class.
This is the reason why we need some kind of architecture that allows exchanging the old class with the new class. Also it is pretty obvious that current instances of the old class can not automatically be transferred to the new version as everything could have changed. So you will also need a custom method that collects and rebuilds those instances.
The approach described in the article uses an Interface instead of an actual class in the first place. This allows to easily exchange the class behind that interface without breaking the code that uses the interface.
Then you need a factory where you ask for instances of that Interface. The factory can now check if the underlying class-file has changed, if so it reloads it and obtains a reference to the new class version. It can now always create an instance of the interface which uses the up-to-date class.
The factory, by that, is also able to collect all created instances in order to exchange them later, if the code base has changed. But the factory should reference them using WeakReference (documentation), else you have a big memory leak because the Garbage Collector would not be able to delete instances because the factory holds references to them.
Okay, now we are able to always obtain up-to-date implementations of an Interface. But how can we easily exchange existing instances. The answer is by using a proxy-pattern (explanation).
It is simple, you have a proxy class which is the actual object you are working with. It has all the methods of the Interface and upon calling methods it simply forwards to the real class.
Your factory, as it has a list of all current instances using WeakReference, can now iterate the list of proxies and exchange their real class with a new up-to-date version of the object.
Existing proxies that are used all around your project will now automatically use the new real version as the proxy itself has not changed, only its internal reference to the real target has changed.
Now some sample code to give you a rough idea.
The interface for the objects you want to monitor:
public interface IExample {
void example();
}
The real class, which you want to rebuild:
public class RealExample implements IExample {
#Override
public void example() {
System.out.println("Hi there.");
}
}
The proxy class that you will actually use:
public class ProxyExample implements IExample {
private IExample mTarget;
public ProxyExample(final IExample target) {
this.mTarget = target;
}
#Override
public void example() {
// Forward to the real implementation
this.mRealExample.example();
}
public void exchangeTarget(final IExample target) {
this.mTarget = target;
}
}
The factory you will mainly use:
public class ExampleFactory {
private static final String CLASS_NAME_TO_MONITOR = "somePackage.RealExample";
private final List<WeakReference<ProxyExample>> mInstances;
private final URLClassLoader mClassLoader;
public ExampleFactory() {
mInstances = new LinkedList<>();
// Classloader that will always load the up-to-date version of the class to monitor
mClassLoader = new URLClassLoader(new URL[] {getClassPath()}) {
public Class loadClass(final String name) {
if (CLASS_NAME_TO_MONITOR.equals(name)) {
return findClass(name);
}
return super.loadClass(name);
}
};
}
private IExample createRealInstance() {
return (IExample) this.mClassLoader.loadClass(CLASS_NAME_TO_MONITOR).newInstance();
}
public IExample createInstance() {
// Create an up-to-date instance
final IExample instance = createRealInstance();
// Create a proxy around it
final ProxyExample proxy = new ProxyExample(instance);
// Add the proxy to the monitor
this.mInstances.add(proxy);
return proxy;
}
public void updateAllInstances() {
// Iterate the proxies and update their references
// Use a ListIterator to easily remove instances that have been cleared
final ListIterator<WeakReference<ProxyExample>> instanceIter =
this.mInstances.listIterator();
while (instanceIter.hasNext()) {
final WeakReference<ProxyExample> reference = instanceIter.next();
final ProxyExample proxy = reference.get();
// Remove the instance if it was already cleared,
// for example by the garbage collector
if (proxy == null) {
instanceIter.remove();
continue;
}
// Create an up-to-date instance for exchange
final IExample instance = createRealInstance();
// Update the target of the proxy instance
proxy.exchangeTarget(instance);
}
}
}
And finally how to use it:
public static void main(final String[] args) {
final ExampleFactory factory = new ExampleFactory();
// Get some instances using the factory
final IExample example1 = factory.createInstance();
final IExample example2 = factory.createInstance();
// Prints "Hi there."
example1.example();
// Update all instances
factory.updateAllInstances();
// Prints whatever the class now contains
example1.example();
}
Attaching an agent at runtime requires use of the attach API which is contained in the tools.jar until Java 8 and is contained in its own module starting from Java 9. The location of the tools.jar and the name of its classes is system-dependent (OS, version, vendor) and as of Java 9 it does not exist at all but must be resolved via its module.
If you are looking for an easy way to access this functionality, try out Byte Buddy which has a subproject byte-buddy-agent for this. Create a Java agent as you are used to it but add anAgent-Main entry where you would put your Pre-Main in the manifest. Also, name the entry method agentmain, not premain.
Using byte-buddy-agent, you can write a program:
class AgentLoader {
public static void main(String[] args) {
String processId = ...
File agentJar = ...
ByteBuddyAgent.attach(processId, agentJar);
}
}
and you are done.
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.
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
I'm using ASM Java library to generate a class X from scratch. Inside one of the static methods of this class I need to push a reference to X.class. Since there isn't yet a X.class I can't use visitLdcInsn. Is there a way to do it?
Well, it's possible (and I'm currently using it) to generate the following code (new X().getClass()), but I'm sure that's not the cleanest way to do it.
With generated code you usually don't need to push the class onto the stack. Anything you can do with a method call is usually available in byte code.
Say you have to call a method with a class, you can push it onto the stack whether it exists or not.
Something I use is the ASMifier. This is useful because you can start with a class which compiles and does what you want as a template and get it to dump all the code needed to recreate the class. This means you don't really need to write most of the code yourself.
public class Main {
public static void main(String... args) throws IOException {
ASMifierClassVisitor cv = new ASMifierClassVisitor(new PrintWriter(System.out));
ClassReader cr = new ClassReader("X");
cr.accept(cv, 0);
}
}
class X {
{
System.out.println("Inside class "+X.class);
}
}
prints
// lots of code
mv.visitLdcInsn(Type.getType("LX;"));
// more code.