Reflection em uma Interface EJB3 - Impossível?

8 respostas
D

Pessoal, estou inventando um Proxy web para atuar como controlador de interface gráfica. Você informa quem é o SessionBean responsável pelas Entities e ele vai mapeado automaticamento todos os processos CRUD. Se funcinar como está aqui na minha caxola, vai ficar fera e open source too…

Porém morri na praia com o EJB3 Session e reflection. Esse é o Erro:

java.lang.IllegalArgumentException: object is not an instance of declaring class

Que ocorre aqui:

Onde:

sessionInstance é um Object criado pelo context.lookup()

Como é que eu sei que ele é o culpado? - Se eu executar um:

System.out.println("sessionInstance class = " + sessionInstance.getClass()); System.out.println("sessionInstance class name = " + sessionInstance.getClass().getName());

21:50:47,099 INFO [STDOUT] sessionInstance class = class $Proxy149
21:50:47,099 INFO [STDOUT] sessionInstance class name = $Proxy149

Resultado: O lookup criou um Proxy RMI, ou sei lá qualquer outra coisa, mas não é uma instância real da classe que precisa ser passada para o invoke fazer o reflection. Como é que eu resolvo essa parada? Tem como fazer um cast de Proxy para Real Class type ??? Existe um Reflection the Proxies?

Valew,

Abraços,

Davi.

8 Respostas

L

[momento de fúria]
Espero que seu projeto não seja um novo Maker :evil:
[/momento de fúria]

Uma coisa você não explicou, de onde vem a variável m (que, suponho eu, seja java.lang.reflect.Method)?

Como você nunca instanciaria m diretamente, você obteve através de um Class. Porém, qual? Da inteface do seu EJB? Ou da implementação do EJB? Se você escolheu a segunda opção, saiba que está conceitualmente errado!

Apesar disso, não posso dizer que é garantido o funcionamento usando a primeira opção (nunca testei pra saber), mas me parece a melhor aposta.

D

O que é Maker ???

Eis o código completo e ele é chamado dentro de um servlet....

public String getPropertie(String name) {
		return this.properties.getProperty(name);
	}

public Object createSession() {
		try {
			Object session = context.lookup(this.getPropertie("ejb3.interface.name"));
			System.out.println("returning new session class = " + session.getClass());
			System.out.println("to string = " + session.toString());
			return session;
		}catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}	

public Object call(String method, Object[] parametersValue) {
		try {
			Class<?> sessionClass = Class.forName(getPropertie(PROP_SESSION_CLASS));
			//Create the Session
			Object sessionInstance = createSession();

			Class<?> paramTypes[] = null;

			if (parametersValue.length > 0) {
				paramTypes = new Class[parametersValue.length];

				for (int i = 0; i < parametersValue.length; i++) {
					paramTypes[i] = parametersValue[i].getClass();
				}	
			}

			//Create the method "call"
			Method m = sessionClass.getMethod(method, paramTypes);

			if (sessionInstance == null) {
				System.out.println("session instance NULL");
			}

			Object response = m.invoke(sessionInstance, parametersValue);

			//Return response
			return response;
		}catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
D

Não tem nada a ver com Maker… Na verdade é um Proxy para que você possar usar os métodos do SessionBean que implementa regras de negócio via chamadas Ajax/etc do browser, Assim vc poderia criar uma interface gráfica que passa uma Entity em XMl, JSON, o que seja, que o proxy entende o que ela é e chama o session correspondente e faz a operação…

na verdade só deixa mais plugável essa etapa…

Mas eae, tem saída???

J

Tente substituir:

Method m = sessionClass.getMethod(method, paramTypes);

por:

Method m = sessionInstance.getClass().getMethod(method, paramTypes);
L

O que retorna?

getPropertie(PROP_SESSION_CLASS)

Uma string que é a interface do EJB, ou que é a classe concreta que implementa a interface?

Jair_Rillo_Junior

Não lí todo o tópico, porém uma das regras do EJB3 é:

“Especificação de EJB3”:
The enterprise bean must not attempt to query a class to obtain information about the declared members that are not otherwise accessible to the enterprise bean because of the security rules of the Java language. The enterprise bean must not attempt to use the Reflection API to access information that the security rules of the Java programming language make unavailable.

Portanto não sei se é uma boa idéia fazer reflection em um SessionBean.

J

Ele nao estah fazendo reflection dentro de um SB, e sim em um cliente SB.

D

Galera achei o erro, desculpe em me antecipar e correr pra cá.

Respondendo:
getPropertie(PROP_SESSION_CLASS) Retorna o nome da interface do EJB.

O erro era que no WAR eu estava usando para teste ele provavelmente estava usando uma versão mais antiga da classe SessionBean. Quando eu coloquei todo mundo no EAR, o reflection funcionou como deveria…, vai entender…

Obrigado pelas dicas e pelas observações de segurança do EJB, ficarei mais atento aos futuros problemas…

Um abraço,

Davi.

Criado 21 de outubro de 2008
Ultima resposta 22 de out. de 2008
Respostas 8
Participantes 4