Search code examples
eclipseeclipse-pluginclassloader

How to get all packages from an Eclipse Plug-in?


// Eclipse PDE 2022-09  
// JDK17
// I get the ClassLoader of org.eclipse.swt
ClassLoader classLoader = ......

// Try to get all packages from it
Package packages[] = classLoader.getDefinedPackages() ;
for ( Package pkg : packages ) {
    println( pkg ) ;
}

// But some packages are missing from the results, like "org.eclipse.swt.awt".

In this scenario, how can I get all the packages ?


Solution

  • This is my way getAllClassName( SWTBundle ) ;

    public record Package( String packageName , List<String> classes , Bundle bundle ){
            
        public Class<?> loadClass(String className) throws ClassNotFoundException {
            if( !classes.contains(className) ) {
                throw new ClassNotFoundException("not found " + className) ;
            }
            return bundle.loadClass( packageName + "." + className ) ;
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(packageName);
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Package other = (Package) obj;
                return Objects.equals(packageName, other.packageName);
        }
    }
        
        
    public Stream<Package> getAllClassName(Bundle bundle) throws BundleException {
        BundleWiring bundleWiring = bundle.adapt(BundleWiring.class) ;
        if( bundleWiring == null ) {
            throw new BundleException( "BundleWiring is null" ) ;
        }
        Collection<String> resources = bundleWiring.listResources("/", "*.class", BundleWiring.LISTRESOURCES_RECURSE);
        List<Package> packageList = new ArrayList<>();
        for (String resource : resources) {
            String className = FilenameUtils.getBaseName( resource ) ;
            String packageName = FilenameUtils.getPathNoEndSeparator( resource ).replace('/','.') ;
            int index = packageList.indexOf(new Package(packageName,null,null)) ;
            ArrayList<String> classes = null ;
            if( index == -1 ) {
                classes = new ArrayList<>() ;
                packageList.add( new Package(packageName,classes,bundle) ) ;
            }else {
                classes = (ArrayList<String>)packageList.get(index).classes ;
            }
            classes.add( className ) ;
        }
        return packageList.stream().sorted( (a,b) -> a.packageName.compareTo(b.packageName) ) ;
    }