• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Creating and iterating instances of every class in given package

 
Ranch Hand
Posts: 310
18
MS IE Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello fellow Ranchers,

I am building a program that utilizes a quite big amount of modules (around 150 at the moment). Every module is just a simple class that implements the same interface. All of those modules (classes) are placed in the same package.

The program must create instance of every class from the modules package, and then execute a method from every instance (the method is present in the interface).

The logic of what I want to achieve could look as following:
1. Obtain all classes from the package com.example.modules
2. Create instances of all the gathered classes, and put them in a list (or any other iterable container)
3. Iterate the list, executing method X from every instance (the method is present in the interface)

I would want to kindly ask for suggestions how I can achieve this. I am a Java beginner, therefore any source code and/or links to the docs would be extremely helpful.

Thank you for your time,
Adam
 
Ranch Hand
Posts: 239
12
Scala IntelliJ IDE Eclipse IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmm...that just sounds...interesting...what is the use case for such a thing? Why do you have 150 classes implementing the same interface? Are you sure that this wouldn't make sense done some other simpler way? Are the 150 different implementations really 150 different bits of logic?
 
Marshal
Posts: 4501
572
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have done something similar to this to build a simple container to execute classes packaged in jar files. These are the steps:

Get a list of all classes in the specified package:
  - get the context ClassLoader
  - use the ClassLoader to get a list of resources for the package name (there will only be one resource)
  - iterate through the resources (or just work with the first element) and:
      - check the protocol associated with the resource URL (jar'ed and non-jar'ed are handled differently)
      - for non-jar'ed, get the file directory for the package from the URL
      - iterate through all the filenames in the directory looking for files ending with class (all the files should be class files)
      - form a fully qualified class name (package name + filename (without the .class suffix))
      - get a class object using the class name (use Class.forName())
      - add the class object to a list of Class<?>

Iterate through the list of class objects and:
  - verify that the class implements the needed interface
  - create an instance of the class
  - call the specific method

 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sounds like just the thing you'd want to use ServiceLoader for. The only drawback is that you have to create the file with the class list yourself, but you can possibly automate that with some build tools. I've done a quick search and found serviceloader-maven-plugin (https://github.com/francisdb/serviceloader-maven-plugin / http://mvnrepository.com/artifact/eu.somatik.serviceloader-maven-plugin/serviceloader-maven-plugin).
 
Andrew Polansky
Ranch Hand
Posts: 310
18
MS IE Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you all for your time to reply to my post.

Scott Shipp wrote:Hmm...that just sounds...interesting...what is the use case for such a thing? Why do you have 150 classes implementing the same interface? Are you sure that this wouldn't make sense done some other simpler way? Are the 150 different implementations really 150 different bits of logic?


I forgot to mention that there are abstract classes that stand between the "module" classes and the interface. Most of those "module" classes are just configuring the settings used by the abstract class they extend.

In more detail:
Those 150 "module" classes represent websites with which my program must interact.

About 100 of those websites are running on a small set of software (around 10 scripts). For this reason, I have created abstract classes that implement interaction logic with those scripts.

Most of those websites aren't using the scripts in their default config - they often use custom code, plugins, and various configurations on software and server side. For this reason, the script implementations are abstract classes that are extended by the "module" classes - any changes in the default behavior of the script are either configured or implemented in the "module" classes. In example, basic configuration is done by calling the abstract class constructor and/or other configuration related methods. Custom code or server specific modifications are handled by overriding methods (like login method).

This organization allows me to easily handle all of the 150 websites. When one gets updated, I can easily navigate to the class that represents given website and change what is needed. So far this system proved to be working nicely.


Ron, thank you very much for the detailed description of the process, and Rob for the idea with ServiceLoader. Your posts gave me a new idea how I can temporarily handle this situation (due to an incoming deadline). For now, I will store the class names in the database. When the classes are needed, I will simply query the database and create new instances using the class names.

Nevertheless, I will have to implement "scanning" of the classes in the package anyway. It will be needed to implement ofter features that are planned for the next iteration on the beginning of 2016. I will come here back with details how I implemented it. Suggestions of Ron and Rob will be definitely very helpful in implementing that. Thank you again for your responses, I really appreciate that.
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome.
 
Hey, check out my mega multi devastator cannon. It's wicked. It makes this tiny ad look weak:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic