Existe uma maneira de forçar um carregador de classe a carregar um pacote, mesmo que nenhuma de suas classes tenha sido carregada?

StackOverflow https://stackoverflow.com/questions/1816730

Pergunta

Digamos que uma base de código Java tenha um pacote chamado "com.example".

Em tempo de execução, podemos obter este pacote ligando

Package p = Package.getPackage( "com.example" ); //(returns null)

Ou até obtenha uma lista de todos os pacotes ligando

Packages[] ps = Package.getPackages();

O problema é: se o carregador de classe ainda não tiver carregado nenhuma classe do pacote, ele não estará disponível para essas chamadas de função. Podemos forçá-lo a carregar o pacote, carregando força uma das classes do pacote primeiro, como esta:

this.getClass().getClassLoader().loadClass( "com.example.SomeClass" );
Package p = Package.getPackage( "com.example" ); //(returns non-null)

No entanto, isso é hacky e exige saber com antecedência o nome de alguma classe que pertence ao pacote.

Portanto, a pergunta é - existe alguma maneira de obter uma instância de pacote pelo nome, independentemente de o carregador de classe ter feito alguma coisa? Minhas suposições sobre como o carregamento/pacotes de classe parecem funcionar nessa situação precisa?

Foi útil?

Solução

Suponho que você precise disso porque precisa inspecionar suas anotações. Caso contrário, você não estaria interessado em ter uma referência de pacote que apenas as operações estão em torno do acesso às anotações. Isso leva à suposição de que você também possui um pacote-info.java definido lá com algumas anotações.

Se você verificar java.lang.Package você verá que o getPackageInfo Basta carregar a classe Package-Info como uma classe comum.

Eu tive o mesmo problema e criei esta solução.

public static Package getPackage(String packageName) throws ClassNotFoundException {
    Class.forName(packageName+".package-info"); // makes sure package info exist and that the class loader already knows about the package
    return Package.getPackage(packageName);
}

Outras dicas

Como alternativa, você pode usar o diretório raiz da classe como ponto de partida e percorrer todos os arquivos *.class e sub -diretórios. Isso só funcionaria se você soubesse onde todos os seus arquivos .class residirão com antecedência.

A causa de tudo isso é que o Java possui carga dinâmica de classe, para que as aulas possam ser carregadas em tempo de execução a partir de locais não conhecidos no horário de compilação ou mesmo no horário de inicialização. Portanto, o conceito de um pacote é apenas um espaço de nome para classes carregadas, não um diretório que você pode usar para procurá -los.

Receio que suas suposições não sejam válidas. Os carregadores de classe fazem pacote de manutenção de livros enquanto carregam aulas.

Você pode passar um curinga para ClassLoader.getResources e forçá -lo a pegar as aulas em um pacote, que, por sua vez, fará o trabalho.

Você pode fazer seu próprio carregador de classe que chama definePackage, mas isso não o ajudará com os carregadores de classe de baunilha usuais em uso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top