{"id":22454818,"url":"https://github.com/waikato/jclasslocator","last_synced_at":"2025-03-27T13:16:41.088Z","repository":{"id":57723965,"uuid":"81174941","full_name":"Waikato/jclasslocator","owner":"Waikato","description":"Java library for analyzing the classpath of an application, used to determine class hierarchies. ","archived":false,"fork":false,"pushed_at":"2022-09-21T21:47:16.000Z","size":133,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-01T17:32:13.135Z","etag":null,"topics":["classpath","java"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Waikato.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-07T06:33:24.000Z","updated_at":"2021-11-18T01:28:53.000Z","dependencies_parsed_at":"2022-09-02T06:54:22.634Z","dependency_job_id":null,"html_url":"https://github.com/Waikato/jclasslocator","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Waikato%2Fjclasslocator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Waikato%2Fjclasslocator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Waikato%2Fjclasslocator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Waikato%2Fjclasslocator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Waikato","download_url":"https://codeload.github.com/Waikato/jclasslocator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245850363,"owners_count":20682647,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["classpath","java"],"created_at":"2024-12-06T07:09:13.022Z","updated_at":"2025-03-27T13:16:41.064Z","avatar_url":"https://github.com/Waikato.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jclasslocator\n\nJava library for analyzing the classpath of an application, e.g., used to \ndetermine dynamic class hierarchies (simply add a jar with additional classes\nin packages that the `ClassLister` monitors and they are automatically located).  \n\nUsed by [ADAMS](https://adams.cms.waikato.ac.nz/).\n\n## Class hierarchies\n\nDefining class hierarchies is very easy. Just supply a `java.util.Properties`\nobject to the `ClassLister.setPackages(Properties)` method that lists for\neach superclass (or interface) the packages that need inspecting.\n\nHere is the basic format:\n\n```INI\nclass.name=package1,package2,...\n```\n\n## Blacklisting\n\nBlacklisting of classes is extremely easy. You just need to supply a\n`java.util.Properties` object to the `ClassLister.setBlacklist(Properties)`\nmethod that lists a comma-separated list of regular expressions for matching\nclass names to exclude. The simplest is to use the full class name of the\nclass to exclude.\n\nHere is the basic format:\n\n```INI\nclass.name=regexp1,regexp2,...\n```\n\n## Example (manual setup)\n\nThe following code is taken from `nz.ac.waikato.cms.locator.example.ClassListerExample`:\n\n```java\nimport nz.ac.waikato.cms.locator.ClassLister;\nimport java.util.Properties;\n\n// configuring the class hierarchies\nProperties pkgs = new Properties();\npkgs.put(AbstractAncestor.class.getName(), \"nz.ac.waikato.cms.locator.example.pkgA,nz.ac.waikato.cms.locator.example.pkgB\");\npkgs.put(SomeInterface.class.getName(), \"nz.ac.waikato.cms.locator.example.pkgA,nz.ac.waikato.cms.locator.example.pkgB\");\n\n// blacklisted classes\nProperties black = new Properties();\nblack.put(AbstractAncestor.class.getName(), \".*C\");  // anything that ends with a capital \"C\"\nblack.put(SomeInterface.class.getName(), \"nz.ac.waikato.cms.locator.example.pkgB.InterfaceImplInternal\");  // specific class\n\n// initialize\nClassLister lister = ClassLister.getSingleton();\nlister.setPackages(pkgs);\nlister.setBlacklist(black);\nlister.initialize();\n\nClass[] classes;\n// abstract class\nSystem.out.println(\"\\nAbstract super class: \" + AbstractAncestor.class.getName());\nclasses = lister.getClasses(AbstractAncestor.class);\nfor (Class cls: classes)\n  System.out.println(\"- \" + cls.getName());\n// interface\nSystem.out.println(\"\\nInterface: \" + SomeInterface.class.getName());\nclasses = lister.getClasses(SomeInterface.class);\nfor (Class cls: classes)\n  System.out.println(\"- \" + cls.getName());\n```\n\nGenerates this output:\n\n```\nAbstract super class: nz.ac.waikato.cms.locator.example.AbstractAncestor\n- nz.ac.waikato.cms.locator.example.pkgA.ConcreteClassA\n- nz.ac.waikato.cms.locator.example.pkgA.ConcreteClassB\n\nInterface: nz.ac.waikato.cms.locator.example.SomeInterface\n- nz.ac.waikato.cms.locator.example.pkgA.InterfaceImplA\n- nz.ac.waikato.cms.locator.example.pkgB.InterfaceImplB\n- nz.ac.waikato.cms.locator.example.pkgB.InterfaceImplC\n```\n\n## Example (using .props files)\n\nInstead of manually creating `java.util.Properties` objects, you can also\nuse `.props` files and load them instead.\n\nListing packages (`ClassLister.props`):\n```INI\nnz.ac.waikato.cms.locator.example.AbstractAncestor=\\\n  nz.ac.waikato.cms.locator.example.pkgA,\\\n  nz.ac.waikato.cms.locator.example.pkgB\n\nnz.ac.waikato.cms.locator.example.SomeInterface=\\\n  nz.ac.waikato.cms.locator.example.pkgA,\\\n  nz.ac.waikato.cms.locator.example.pkgB\n```\n\nBlacklisting classes (`ClassLister.blacklist`)\n```INI\nnz.ac.waikato.cms.locator.example.AbstractAncestor=.*C\n\nnz.ac.waikato.cms.locator.example.SomeInterface=nz.ac.waikato.cms.locator.example.pkgB.InterfaceImplInternal\n```\n\n```java\nimport nz.ac.waikato.cms.locator.ClassLister;\nimport java.util.Properties;\n\n// loading the props files (path might need adjusting)\nProperties pkgs = ClassLister.load(\"ClassLister.props\");\nProperties black = ClassLister.load(\"ClassLister.blacklist\");\n\n// initialize\nClassLister lister = ClassLister.getSingleton();\nlister.setPackages(pkgs);\nlister.setBlacklist(black);\nlister.initialize();\n\nClass[] classes;\n// abstract class\nSystem.out.println(\"\\nAbstract super class: \" + AbstractAncestor.class.getName());\nclasses = lister.getClasses(AbstractAncestor.class);\nfor (Class cls: classes)\n  System.out.println(\"- \" + cls.getName());\n// interface\nSystem.out.println(\"\\nInterface: \" + SomeInterface.class.getName());\nclasses = lister.getClasses(SomeInterface.class);\nfor (Class cls: classes)\n  System.out.println(\"- \" + cls.getName());\n```\n\n\n## Logging\n\nLogging is by default restricted to `WARNING` or higher (like `SEVERE`).\nHowever, you can enable logging for debugging purposes via environment \nvariables:\n\n* `nz.ac.waikato.cms.locator.ClassCache.LOGLEVEL`\n* `nz.ac.waikato.cms.locator.ClassLister.LOGLEVEL`\n* `nz.ac.waikato.cms.locator.ClassLocator.LOGLEVEL`\n* `nz.ac.waikato.cms.locator.ClassPathTraversal.LOGLEVEL`\n\nThese environment variables can take the following values:\n```\n{OFF|SEVERE|WARNING|INFO|CONFIG|FINE|FINER|FINEST}\n```\n\n## No classpath\n\n### Fixed list of classnames\nIn case the classpath is empty, i.e., `System.getProperty(\"java.class.path\")` \nreturns an empty string, you can initialize the `ClassCache` instance with a\nfixed list of class names. For that you need to provide an instance of the \n`FixedClassListTraversal` class to the `ClassLister.getSingleton(ClassTraversal)`\nmethod. `FixedClassListTraversal` can be instantiated either with a \n`java.util.List\u003cString\u003e` that lists all class names or with an `java.io.InputStream`\nobject, from which to read the class names. Empty lines and lines starting with\n`#` get automatically skipped.\n\nThe example classes could be stored in the file `nz/ac/waikato/cms/locator/example/fixed.classes` \nlike this:\n\n```\n# first package\nnz.ac.waikato.cms.locator.example.pkgA.ConcreteClassA\nnz.ac.waikato.cms.locator.example.pkgA.ConcreteClassB\nnz.ac.waikato.cms.locator.example.pkgA.InterfaceImplA\n\n# second package\nnz.ac.waikato.cms.locator.example.pkgB.ConcreteClassC\nnz.ac.waikato.cms.locator.example.pkgB.InterfaceImplB\nnz.ac.waikato.cms.locator.example.pkgB.InterfaceImplC\nnz.ac.waikato.cms.locator.example.pkgB.InterfaceImplInternal\n```\n\nThe code therefore looks like this for initializing the `ClassLister`:\n\n```java\nFixedClassListTraversal fixed = new FixedClassListTraversal(\n  ClassLoader.getSystemResourceAsStream(\"nz/ac/waikato/cms/locator/example/fixed.classes\"));\nClassLister lister = ClassLister.getSingleton(fixed);\n```\n\nThe above code is taken from `nz.ac.waikato.cms.locator.example.ClassListerExampleFixedClassList`.\n\n\n### Classnames from properties\n\nExample `nz.ac.waikato.cms.locator.example.ClassListerExamplePropertiesBasedClassList` shows\nhow to initialize from a `java.utils.Properties` object. Each of the properties contains a\ncomma-separated list of classnames.\n\n\n## Other useful methods\n\n* `ClassLister.toProperties()` - returns the class hierarchies as a \n  `java.util.Properties` object. The key of a property is the superclass name\n  and the associated value is the comma-separated list of classnames.\n* `ClassLister.toPackages()` - returns the class hierarchies as a \n  `java.util.Properties` object. The key of a property is the superclass name\n  and the associated value is the comma-separated list of packages.\n\n\n## Maven\n\nAdd the following dependency to your `pom.xml`:\n\n```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003ecom.github.waikato\u003c/groupId\u003e\n      \u003cartifactId\u003ejclasslocator\u003c/artifactId\u003e\n      \u003cversion\u003e0.0.22\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwaikato%2Fjclasslocator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwaikato%2Fjclasslocator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwaikato%2Fjclasslocator/lists"}