I use in my project a lib with some class with a lot of static field and other stuffs, who are indirectly updated and consulted at runtime in my app.
I can't update or ignore or mock this class.
How can I re-execute the method who initialise the static field of a class?
I'm currently writing test in my app, which trigger this class.
I want the static field of this class to be at their init state each time I start my app.
The issue is, setting manualy those static field is not possible, it would be too complexe. I need them to be put at their initial state "automaticaly"
I can't change anything to the code of the class, because it's in a lib.
Any idea how I can do that? With reflexion, maybe?
If resetting static fields manually are too complex and classes are stateless, one of the way could be to use custom class loader and reload your classes whenever required.
This article may provide some idea about loading and reloading classes.
You should watch out for performance hit.
Related
Let's say I am making a list of possible items in the game. Every one of them is deriving from the class Item and all of them are placed in the specific package "com.name.app.items".
I want to make a list of them created dynamically, without adding any external information apart from the file containing the class.
I tried getting all files in a package and computing them accordingly but to no avail. Reflection simply refuses to cooperate. No matter what configuration I use, a scanner always returns an empty set.
My second thought was to to simply invoke a static method like ItemDatabase.add(this) but as far as I know it isn't possible without creating an instance of this object or calling a static method from outside.
Is there a go-to method for resolving this kind of issue? Or it is necessary to (apart from declaring the very class) notifying some registry of it's existence?
After many hours of research I finally found a suitable answer.
A simple Gradle task did the job for me as Reflections, ClassGraph etc. doesn't work very well on Android.
Bear in mind that if you would like to read what classes are available in a package on runtime - it will be a very difficult task so find another solution or prepare yourself for a long journey.
I'm trying to execute the same code in every subclass of a class once the class is loaded. I need to scan the classes fields using reflection to generate an outline of the data container/class.
Is there any way to do this without invoking a method of the superclass in every subclass once it is initialized? (e.g. inheriting the static initializer of the super class)
EDIT: I'm writing a library that manages some data objects. When I want to store more data in them, I'd usually subclass them. But as this get's pretty annoying when handing them back to the library and having to cast, check instanceof all the time, I wanted to create a system of "data components", that could be added to this data objects. I want to be able to use these data components in code by directly accessing their members (not via id or string), serialize them and let the user edit them in a dynamic GUI. For generating the GUI (and for serializing) I need to know the fields of the "data component classes", that were handed to my library, but I don't want to force the main application to make a library call to register each new data component class. Therefore I'm asking if it's possible to do this automatically for each subclass of a given "data component" class, that is loaded. (without classpath scanning)
Another solution would be to just declare a getFields() method in the data component superclass which automatically scans/registers the subclass when needed, but this would add some delay (i don't know how fast/slow reflection is) on the first call when the application is not in init anymore and therefore should be running as fast as possible. (I'd like to do the scanning beforehand)
In android, are using static variables a recommended practice?
E.g, implementing a Singleton pattern in Java, I usually do:
private static A the_instance;
public static A getInstance() {
if (the_instance == null) {
the_instance = new A();
}
return the_instance;
}
Also, when does this get cleaned up by the Android JVM?
static fields are attached to the Class instance as a whole, which is in turn attached to the ClassLoader which loaded the class. the_instance would be unloaded when the entire ClassLoader is reclaimed. I am 90% sure this happens when Android destroys the app (not when it goes into the background, or pauses, but is completely shut down.)
So, think of it as living as long as your app runs. Is Singleton a good idea? People have different views. I think it's fine when used appropriately, myself. I don't think the answer changes much on Android. Memory usage isn't the issue per se; if you need to load a bunch of stuff in memory, that's either a problem or it isn't, regardless of whether you encapsulate the data in a Singleton.
I think static variables are OK.
This is what Android doc says:
http://developer.android.com/guide/appendix/faq/framework.html
How do I pass data between Activities/Services within a single application?
A public static field/method
An alternate way to make data accessible across Activities/Services is to use public static fields and/or methods. You can access these static fields from any other class in your application. To share an object, the activity which creates your object sets a static field to point to this object and any other activity that wants to use this object just accesses this static field.
Contrary to what other people say - it is more than ok. Granted, it has some structure to it. In the official googlesamples/android-architecture repo it is used under todo-mvp-clean (Todo app implementing MVP pattern and following Clean Architecture principles).
Check out this file.
What you can see is a lot of static methods referencing singleton getters.
Modern, less error prone and convenient alternative is the Dagger DI framework.
I'm not sure if such approach is good for mobile platform where you have limited memory available to you. Not to mention that the application will be run on a multi-tasking enabled device.
I think, this approach may hog memory from the device but I have no document to support this. Perhaps someone who's more educated than me can share their thoughts.
No. Don't do it! Singleton is an anti-patern!. Instead, use dependency injection, whether via a framework (such as via Dagger or Roboguice) or by explicitly passing the instantiated object.
Say I have a class with a few fields all marked with a custom annotation. In my case it is #inject, because this is being used for dependency injection. How can I run a method in a separate class each time that annotation is used in my a class? In other words, each time a class is loaded the annotation runs a method that will collect the field data and in turn set the field.
I already have the entire system set up for collecting the resources, but I need some direction on how to actually run that code when the class with #inject annotation is loaded. Is this something that can be done by defining some sort of method in the annotation interface that performs the data collection?
My initial thought is to use a custom class loader, but I don't want to have to set the class loader when I use this jar in other projects. Is there a way to set a custom class loader programmatically for specific classes at runtime? I'm already doing a lot of pre-runtime reflection stuff and i'll already know which classes need to be loaded with a custom loader. Its just a matter of not knowing or if its even possible to set a custom loader on a class from within the code.
Can a classloader even be used to perform tasks such as pre-populating fields, or am I running off on a wrong tangent here? I just need a little direction on the most common way this type of thing is done (pre-populating class fields at runtime).
I was overthinking this problem. You cannot actually run code automatically prior to loading a class (unless its a servlet filter etc). In my situation the answer was to create an instance based on a specific class that already held the resource data I needed. Similar to how Google's Guice does it.
See this question for more insight: How does Guice Populate Annotated Fields
You can use injectors from Google Guice or Spring Framework.
In one of requirement we have to make available certain attributes through out the web-application so that we can show them in the drop down where ever we want them.So we have few options
We are planning to create a utility class with some static fields which will be assigned values at application startup or when the first request for that list arrived.
Idea is to read a property file and create a List<String> and assign it to the static field so that when ever some one need access to it all he/she need the following call
GeneralUtil.getList()
Since we are working in a web-application one option is to create a listner like
public final class MyListener
implements ServletContextListener {
}
and than read the property file on the contextInitialized method and assign the read value to the static field so that they will be available after startup.
other option is
to create a static block inside GeneralUtil class and place the file read logic inside the static block so that once the class loaded by the cotainer static field will be initialize and we need not to load it for subsequent request.
my question is which of these should be preferred approach and if there is any other best way to achieve this.All i want to avoid to place List in ApplicationContext or any such approach.
I would go with the ServletContextListener approach and an accessor for your property. It seems cleaner and more intuitive than static initializer block.
I would find it also easier if in the future you would like to separate the initialization logic into several methods. In separate class with well defined responsibility it will be easier to do (and to read!) than in some 'GeneralUtil god-like class'.
If you're limited to Servlets I think that's the best and simplest solution.
However, if you're working with EJB's you could as well use #Singleton EJB with #Startup. If you're working with CDI you could use #ApplicationScoped CDI bean.
HTH.
and than read the property file on the contextInitialized method and assign the read value to the static field so that they will be available after startup.
Instead of static variables,place the created List<String> in the servletContext object at contextInitialized(ServletContextEvent sce) method
Note that you could retrieve the servletContext object from ServletContextEvent.
The static solution would mean ThreadLocal and using serialization.
A application scoped bean (yeah, probably best placed in the ApplicationContext) would make the most sense. You could still wrap it in a kind of GeneralUtil wrapper. The solution of Piotr Nowicki is best.
I think you did not want to hear this solution.
Why dont you want to add these values in ApplicationContext ? It makes sense since its going to be same for whole of the application ?
Of the two option you have mentioned its better to load these properties in MyListener instead of static block, reasoning if your load fails your GeneralUtil class wont be loaded unless you specifically catch exception and ignore it, which means application cannot be used.
I've used a ServletContextListener for a similar use case and it worked out just fine. I think this is the easiest and most straightforward solution. Just put the attributes into the ServletContext via setAttribute(name, object) and retrieve them anywhere in your application via getAttribute(name).