0

Given I have a string with a simple class name:

String className = "myClassName";

and I know for sure there is a class with this name somewhere under:

"com.automation.qa.company.tests...."

How can I get the canonical name for this class? Please help me find the best solution in Java.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
goraccio
  • 21
  • 2
  • Welcome to Stack Overflow. Please take the [tour] to learn how Stack Overflow works and read [ask] on how to improve the quality of your question. Please show your attempts you have tried and the problems/error messages you get from your attempts. – Progman Jan 26 '22 at 20:54
  • Related question: https://stackoverflow.com/questions/2548384/java-get-a-list-of-all-classes-loaded-in-the-jvm – sorifiend Jan 26 '22 at 21:05
  • 1
    @Progman Only one question was asked, "How can they get the canonical name for a class under some unknown set of packages?" I don't know how you can interpret this as "not focused" – Edwin Buck Jan 26 '22 at 21:09

1 Answers1

0

Create a method that adds the possible package names to the under specified class name, and then checks to see if it can load the class using Class.forName(...).

Below is an example that will search all the Packages accessible by the current class loader. You might want to put a filter into it to keep the search for your class only under a specific part of the accessible packages.

public String findClass( String shortName) {
  for (Package pack : Package.getPackages()) {
    try {
      String resolvedName = pack.getName() + "." + className;
      Class class = Class.forName(resolvedName);
      return resolvedName;
    } catch (ClassNotFoundException e) {
      // intentionally blank
    }
  }
  return null;
}
Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
  • thank you so much! Greatly appreciate your help! It works fine. – goraccio Jan 26 '22 at 21:27
  • @goraccio Glad to help. Good luck on the rest of your program! – Edwin Buck Jan 26 '22 at 22:34
  • Presumably there should be a ".", and the variable should be "shortName"? `String resolvedName = pack.getName() + "." + shortName;` – M. Justin Jan 27 '22 at 09:06
  • @M.Justin Yes, you are right. – Edwin Buck Jan 27 '22 at 14:09
  • 1
    And ideally, this method should return a List, or maybe Set of Strings. There might be more classes that share the class name. And I guess: there is a good chance that later on, the actual class object will be needed. So why return String, when you could just collect the created Class objects? – GhostCat Jan 27 '22 at 14:14
  • @GhostCat True, but I don't fully know what they intend to do, and they asked in a way that implied one `class`. Of course, I could also have returned an `Optional` of the class, or something else too. I'll let the asker "bend" the method into his own needs, the key point being that I don't believe he knew about `Package.getPackages()`. He wanted only packages under a specific package tree too, and I didn't add that because it's trivial for him to do a string compare on `pack.getName()`; but, he didn't balk at that so I guess he knows a bit of Java. – Edwin Buck Jan 27 '22 at 14:18
  • 1
    I disagree on Optional. The point is, just by definition, there can be more than ONE class with a name. Only picking the first one found, or going with Optinal that suggests "there is either 0 or 1" ... is very likely: just wrong. As for example, it makes your application very dependent on the order of classes the classloader(s) maintain. This could lead to very nasty bugs. – GhostCat Jan 27 '22 at 14:22
  • @GhostCat I believe you are excessively concerned about this point, even when we don't know if the code that uses this proposed method can process collections. Anyone who can read Java, and report it "work(s) for them" when they had to fix a small error in it, can correctly read the code and see it returns only the first found item. Claiming that they would be confused on this matter is odd, as it is both the default behavior of the Java ClassLoader and obvious from the code flow logic. If they want a `List` they likely can modify it without me pedantically telling them they must have one. – Edwin Buck Jan 27 '22 at 17:00
  • Well, your content might sit here for many years to come, hopefully. Hundreds, if not thousands of people might read it, with very different level of experience. For a newbie, it isn't necessary clear that the same class name might show up in different packages, and that the order in which those are found can change easily for various "external" reasons. Mentioning that is thus critical imho. – GhostCat Jan 27 '22 at 20:27