Jump to content
zecapistolas

Eclipse JDT - Obter todas as Classes de um determinado projecto

Recommended Posts

zecapistolas

Viva,

Já alguém usou Eclipse JDT?  🤔

Há dois dias que estou a insistir  :wallbash: nisto e não consigo criar uma função que me retorne todas as classes de um determinado projecto....

Código fonte até ao momento:

IJavaProject javaProject = JavaCore.create(ip); // ip é do tipo IProject
IPackageFragment[] packages;
try
{
    packages = javaProject.getPackageFragments();

    for (IPackageFragment mypackage : packages)
    {
        if (mypackage.getKind() == IPackageFragmentRoot.K_SOURCE)
        {
            System.out.println("Source Name " + mypackage.getElementName());
            System.out.println("Number of Classes: " + mypackage.getClassFiles().length);
        }
        else if (mypackage.getKind() == IPackageFragmentRoot.K_BINARY)
        {
            System.out.println("Binary Name " + mypackage.getElementName());
            System.out.println("Number of Classes: " + mypackage.getClassFiles().length);
        }
    }
} catch (JavaModelException e) {
    e.printStackTrace();
}

Mas com isto obtenho sempre Number of Classes: 0 para todos os packages do projecto!

Alguma dica?  :D

cumps  :)

Share this post


Link to post
Share on other sites
shumy

Já utilizei a algum tempo.

Faz um print do projecto: ip.getName()

E penso que tens de verificar se é um projecto java:

if(ip.isNatureEnabled("org.eclipse.jdt.core.javanature")) {
    IJavaProject javaProject = JavaCore.create(ip);
}


Aqui há coisa de 2 anos fazia umas malhas de croché, depois fartei-me e fui para informática!

Share this post


Link to post
Share on other sites
zecapistolas

Já utilizei a algum tempo.

Faz um print do projecto: ip.getName()

E penso que tens de verificar se é um projecto java:

if(ip.isNatureEnabled("org.eclipse.jdt.core.javanature")) {
    IJavaProject javaProject = JavaCore.create(ip);
}

O nome do projecto é relevante?! É, Calculator.

Sim, tenho que verificar se é um projecto Java, não tinha isso em consideração....

E em relação a obter o nome de todas as classes, tens alguma ideia?

cumps :cheesygrin:

Share this post


Link to post
Share on other sites
shumy

O nome do projecto é só para saber se é o esperado.

Calculator é um projecto Java?

As classes, se não estou em erro são as unidades de compilação:

for (ICompilationUnit unit : mypackage.getCompilationUnits()) {
		System.out.println("Source file " + unit.getElementName());
}


Aqui há coisa de 2 anos fazia umas malhas de croché, depois fartei-me e fui para informática!

Share this post


Link to post
Share on other sites
shumy

Já agora, estás a fazer algum plugin? É que dependendo do objectivo, pode-se utilizar reflection do Java.


Aqui há coisa de 2 anos fazia umas malhas de croché, depois fartei-me e fui para informática!

Share this post


Link to post
Share on other sites
zecapistolas

O nome do projecto é só para saber se é o esperado.

Calculator é um projecto Java?

Sim, Calculator é um projecto Java.

As classes, se não estou em erro são as unidades de compilação:

for (ICompilationUnit unit : mypackage.getCompilationUnits()) {
		System.out.println("Source file " + unit.getElementName());
}

É só dizer que assim, tenho apenas o nome da classe.... e com IClassFile (que era o que eu queria) teria acesso ao bytecode da class, ao seu path, etc.... Dá para obter ou criar IClassFile ?  🤔

Já agora, estás a fazer algum plugin? É que dependendo do objectivo, pode-se utilizar reflection do Java.

Sim, estou a fazer um plugin para o Eclipse, e uma das primeiras tarefas é determinar quais as classes existentes num determinado ficheiro....

Não estou familiarizado com esse reflection do Java, o que é?

cumps  :cheesygrin:

Share this post


Link to post
Share on other sites
shumy

Consegues tirar muito mais informação de ICompilationUnit.

for (IType type : unit.getAllTypes()) {
    IMethod[] methods = type.getMethods();
    for (IMethod method : methods) {
        System.out.println("Method Name: " + method.getElementName());
        System.out.println("Signature: " + method.getSignature());
        System.out.println("Return Type: " + method.getReturnType());
    }
}

Se estás a trabalhar com esses pormenores, recomendo instalar o plugin AST View:

http://www.eclipse.org/jdt/ui/astview/index.php

O reflection não deve dar para o que queres, já que é um plugin.

O reflection vem com o Java SE e dá para tirar este tipo de informações, mas é necessário que as classes estejam carregadas na memória do classpath. Tipo, um programa pode analisar as suas próprias classes. Eu utilizo muito isto é para recolher informações das anotações.


Aqui há coisa de 2 anos fazia umas malhas de croché, depois fartei-me e fui para informática!

Share this post


Link to post
Share on other sites
zecapistolas

Consegues tirar muito mais informação de ICompilationUnit.

for (IType type : unit.getAllTypes()) {
    IMethod[] methods = type.getMethods();
    for (IMethod method : methods) {
        System.out.println("Method Name: " + method.getElementName());
        System.out.println("Signature: " + method.getSignature());
        System.out.println("Return Type: " + method.getReturnType());
    }
}

Sim, já tinha experimentado que mais informação podia retirar do ICompilationUnit.

Mas continuo sem perceber porque não posso utilizar ou porque não consigo utilizar o método getClassFiles() ....  🤔

O projecto está compilado e as classes existem, não percebo o porque de não consigar utilizar....

cumps  :cheesygrin:

Share this post


Link to post
Share on other sites
shumy

Estive a efectuar uns testes (já agora para repembrar o PDE).

A má notícia é que também não consegui utilizar o getClassFiles().

A boa é que o java reflection pode de facto ajudar.

Consegui localizar e carregar o file binário para a unidade de compilação com o seguinte código:

//for any ICompilationUnit => unit
try {
String[] classPaths = JavaRuntime.computeDefaultRuntimeClassPath(unit.getJavaProject());
URL[] urls = new URL[classPaths.length];
for (int i = 0; i < classPaths.length; i++){
	String path = "file:///" + classPaths[i];
	if(!path.endsWith(File.separator))
		path += File.separator;

	System.out.println("adding to URL classpath: " + path);
	urls[i] = new URL(path);
}

ClassLoader loader = new URLClassLoader(urls);

String className = mypackage.getElementName() + "." + unit.getElementName().split("\\.")[0];

System.out.println("loading class: " + className);
Class<?> clazz = loader.loadClass(className);

//test the new loaded class with Java reflection...
Object classInstance = clazz.newInstance();		//invoke default constructor
Method testMethod = clazz.getMethod("test");	//get method 'test' with no args
testMethod.invoke(classInstance);				//in my test this invocation will return 'Hello World'

} catch (Exception e) {
throw new RuntimeException(e);
}


Aqui há coisa de 2 anos fazia umas malhas de croché, depois fartei-me e fui para informática!

Share this post


Link to post
Share on other sites
zecapistolas

Estive a efectuar uns testes (já agora para repembrar o PDE).

A má notícia é que também não consegui utilizar o getClassFiles().

A boa é que o java reflection pode de facto ajudar.

Consegui localizar e carregar o file binário para a unidade de compilação com o seguinte código:

//for any ICompilationUnit => unit
try {
String[] classPaths = JavaRuntime.computeDefaultRuntimeClassPath(unit.getJavaProject());
URL[] urls = new URL[classPaths.length];
for (int i = 0; i < classPaths.length; i++){
	String path = "file:///" + classPaths[i];
	if(!path.endsWith(File.separator))
		path += File.separator;

	System.out.println("adding to URL classpath: " + path);
	urls[i] = new URL(path);
}

ClassLoader loader = new URLClassLoader(urls);

String className = mypackage.getElementName() + "." + unit.getElementName().split("\\.")[0];

System.out.println("loading class: " + className);
Class<?> clazz = loader.loadClass(className);

//test the new loaded class with Java reflection...
Object classInstance = clazz.newInstance();		//invoke default constructor
Method testMethod = clazz.getMethod("test");	//get method 'test' with no args
testMethod.invoke(classInstance);				//in my test this invocation will return 'Hello World'

} catch (Exception e) {
throw new RuntimeException(e);
}

Porque acaso já me tinha lembrado de usar o loadClass para carregar a Class em questão, e acho que vou optar por essa alternativa.... Obrigado pelo pedaço de código....

cumps  :P

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.