Making a dynamic list of all classes in a package - java

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.

Related

Using non-created classes in current class

Scenario
This question may be a question about conventions, but Java might have a built-in way to do this. I'm explaining my problem with a scenario:
We are three people working on a project, and we're all doing different parts, and working on different git branches, all of which will be needed in the end project.
My part of the program runs the TUI (let's call the class Startmenu), which requires to run functions from an instance of the Database class. In my switch cases, I know the future code from the other branch will allow me to simply run db.printElements(), as an example.
Problem
Nevertheless, this is the problem: I cannot define Database db; in the class structure, nor can I assign my Startmenu() constructor to take a Database db as an input such as Startmenu(Database db), because it does not yet exist.
In practice, how do I solve this issue? Currently, I'm commenting out the parts that require parts of the other code, and replace it with poisoned code instead, as a placeholder. This doesn't seem like the best idea.
I know a solution is to create the Database class, with empty functions for those functions I will be needing right now, but this will mess with git instead.
tl; dr: How can I prepare my own files to use code that does not yet exist, which will appear "magically" by other people over time?
All components in your project should have specified an interface to exchange information across layers and other Java components during the design phase.
You can early commit and share these interfaces, so other colleagues can provide their own testing implementations or mock behaviours.

Is there a way to get the IJavaElementDelta object from IResourceDelta?

I'm working on an Eclipse plugin that enables traceability. I am implementing a notification system that tells the user whenever a traced item changes (is removed, renamed or edited) and for that purpose I implemented an IResourceChangeListener, but that doesn't give me all the support that I want for Java elements.
For example, when I rename a Java method inside a .java file, it only tells me which file has been edited, but I would like to have the info about the method as well. I know that this can be achieved with implementing the IElementChangedListener, but is there any way around it? Do I really have to implement two listeners (ResourceListener for other files and ElementChangedListener just for java elements) or can I somehow get the IJavaElementDelta (normally obtained from the ElementChangedListener) from the IResourceDelta? Thanks!
These two deltas are completely unrelated. You need to use both listeners.
Try to check this link example 5. There is some method with this description:
Converts an IResourceDelta and its children into
the corresponding IJavaElementDeltas.
Return whether the delta corresponds to a resource on the classpath.
If it is not a resource on the classpath, it will be added as a non-java
resource by the sender of this method.
So I suppose it could be possible.
The links leads here which should you check ass well. Method public void processJavaDelta(IJavaElementDelta delta)

reflection or runtime class declaring?

well I have a simple question.
we are working on a simple application server(like), and this server accepts clients business at runtime without restarting the server.
When user implements it's business and deploy it to the server, server just try to find out the archive descriptor, and load the modules, and it works good.
some operations need to much reflection calls, and for each call they called again and again. for example there is a method which accepts any object, then search for a certain field witch has signed by a annotation and do some business with it, so if we call this method 1000 times with one same object, this is going to reflect 1000 times.
my question is, is it efficient? I mean doesn't it eat up the CPU?! the only possible solution I'm thinking is that create a class and compile it for each object(maybe wrapper) and the method will just find out the wrapper class. but I know this may make the system complex, and hard to debug.
current solution is working, but I think doing a work 1000 times is kinda not logical even it's simple and easy.
Thanks in advanced.
The use of reflection to dynamically load classes at runtime is not a bad choice per-se. Based on your description, you should provide an extensible framework that allows your client to make an implementation, and run their business logic based on that instead of some implicit run-time annotated magic.
A good real-world example for this off the top of my head is The Servlet API.
for example there is a method which accepts any object, then search
for a certain field witch has signed by a annotation and do some
business with it, so if we call this method 1000 times with one same
object, this is going to reflect 1000 times.
In this case I suggest you to use caching. After reflection is finished you'll know class name and the field name. Store them in a HashMap with Class type key and a Method as a value.
Next time you invoke "the method" check cache first.

Can eclipse convert/refactor a method to a class?

This seems like it should be fairly straight-forward, but I can't see anything obvious. What I basically want to do it to point at a method and refactor->extract class. This would take the method in question to a new class with that method as top level public API. The refactoring would also drag any required methods and variables along with it to the new class, deleting them from the old class if nothing else in the old class is using it.
This is a repetitive task I often encounter when refactoring legacy code. Anyway, I'm currently using Eclipse 3.0.2, but would still be interested in the answer if its available in a more recent version of eclipse. Thanks!
I don't think this kind of refactoring exists yet.
Bug 225716 has been log for that kind of feature (since early 2008).
Bug 312347 would also be a good implementation of such a refactoring.
"Create a new class and move the relevant fields and methods from the old class into the new class."
I mention a workaround in this SO answer.
In Eclipse 3.7.1 there is an option to move methods and fields out of a class. To do so:
Make sure the destination class exists (empty class is fine, just as long as it exists in the project).
In the source class, select the methods that you want to remove (the outline view works great for this), right click on the selection, and choose Move
Select the destination class in the drop down/Browse
Your members are now extracted. Fix any visibility issues (Source > Generate Getters and Setters is very useful for this) and you are all set.
This seems like it should be fairly
straight-forward...
Actually, Extract Class is one of the more difficult refactorings. Even in your simple example of moving a single method and its dependencies, there are possible complications:
If the moved method might be used in code you don't know about, you need to have a proxy method in the original class that will delegate to (call) the moved method. (If your application is self-contained or if you know all the clients of the moved method, then the refactoring code could update the calling code.)
If the moved method is part of an interface or if the moved method is inherited, then you will also need to have a "proxy method".
Your method may call a private method/field that some other method calls. You need to choose a class for the called member (maybe in the class that uses it the most). You will need to change access from "private" to something more general.
Depending on how much the original class and the extracted class need to know about each other, one or both may need to have fields initialized that point to the other.
Etc.
This is why I encourage everybody to vote for bug 312347 to get fixed.
Have you tried the Move feature of the Refactor group ? You can create a helper class and move there anything you want.

Problem with static attributes

My problem is that I'm working on a project that requires me to run multiple instances of someone elses code which has many static attributes/variables, which causes all the instances to share those resources and, well, crash. I can run multiple instances of this other person's program if I create a .jar file off of it and open it multiple times by running the .jar in windows, but running calling the "main" method multiple times in my code (which is what I need to do) won't work.
I thought about creating a .jar and using Runtime.getRuntime().exec( "myprog.jar" ); to call the program multiple times, but that won't work for me since I have to pass an instance of my object to this new program and I don't think this solution would allow for that.
PS: This is also posted in the Sun forums, so I`ll post the answer I get there here or the answer I get here there naturally giving proper credit once I this is solved =P.
Remember that a static element in Java is unique only in the context of a classloader (hierarchy); a class is uniquely identified in a JVM by the tuple {classloader, classname}.
You need to instantiate isolated classloaders and load the jar using that class loader. Each loaded class (and thus statis elements) are unique in their classloader and will not interfere with one another.
I'd say you have three alternatives:
Refactor the legacy application so that it doesn't use static attributes. If you can do this, this may be the best solution in the long term.
Continue with your approach of launching the legacy application in a separate JVM. There are a number of ways that you can pass (copies of) objects to another JVM. For example, you could serialize them and pass them via the child processes input stream. Or you could stringify them and pass them as arguments. In either case, you'll need to create your own 'main' class/method that deals with the object passing before calling the legacy app.
I think you should be able to use classloader magic to dynamically load a fresh copy of the legacy application each time you run it. If you create a new classloader each time, you should get a fresh copy of the legacy application classes with a separate set of statics. But, you have to make sure that the legacy app is not on your main classpath. The problem with this approach is that it is expensive, and you are likely to create memory leaks.
The description is a little confusing.
If you are running the code multiple times, you are running multiple independent processes, each running in its own JVM. There is no way that they are actually sharing the values of their static fields. Java doesn't let you directly share memory between multiple VMs.
Can you elaborate more (ideally with examples and code) what the attributes are defined as and what kind of failures you are getting? This may be completely unrelated to them being static.
In particular, what exactly do you mean by shared resources? What resources are your programs sharing?
The proper approach was already suggested - using custom ClassLoaders. Another thing comes to my mind, which might seem ugly, but will probably do, and is a bit more object-oriented approach.
The legacy code is used for its operations, and it incorrectly uses static instead of instance variables. You can fix that using inheritance and reflection:
create (or reuse) an utility class that copies instance variables to static ones
extend the classes in question and provide the same instance variables as the static ones
override all methods. In the overriding methods use the utility to copy the state of the current object to the static variables, and then delegate to (call) the super methods.
Then start using instance of your class, instead of the legacy ones. That way you will simulate the proper behaviour.
Have in mind this is NOT thread-safe.

Categories