seguinte: passei a ter problemas com um projeto que estava rodando muito bem, a partir do momento de resolvi utilizar lambdas nele… como mencionei no título, o projeto usa: VRaptor 4, Tomcat 8.0.9 e Java 8… o erro que dá é aquele mesmo de quando você tem o javassist desatualizado, por que ele não está preparado para ler as lambdas… demais códigos essencialmente Java 8 como a API de datas funcionam bem… o problema é realmente com lambdas… pois então, já tendo visto o erro do javassist e tendo pesquisado e resolvido o mesmo, fui direto nele… coloquei nas libs a ultima versão (javassist 3.18.2 GA) do mesmo… não resolveu!! mas reparando bem no stacktrace nota-se que o mesmo se refere ao paranamer:
25-Aug-2014 11:30:06.895 SEVERE [http-apr-8080-exec-7] org.apache.catalina.core.StandardContext.filterStart Exception starting filter vraptor
java.lang.ArrayIndexOutOfBoundsException: 22967
at com.thoughtworks.paranamer.BytecodeReadingParanamer$ClassReader.accept(BytecodeReadingParanamer.java:563)
at com.thoughtworks.paranamer.BytecodeReadingParanamer$ClassReader.access$200(BytecodeReadingParanamer.java:338)
at com.thoughtworks.paranamer.BytecodeReadingParanamer.lookupParameterNames(BytecodeReadingParanamer.java:103)
at com.thoughtworks.paranamer.AnnotationParanamer.lookupParameterNames(AnnotationParanamer.java:110)
at com.thoughtworks.paranamer.CachingParanamer.lookupParameterNames(CachingParanamer.java:90)
at com.thoughtworks.paranamer.CachingParanamer.lookupParameterNames(CachingParanamer.java:83)
at br.com.caelum.vraptor.http.ParanamerNameProvider.parametersFor(ParanamerNameProvider.java:50)
at br.com.caelum.vraptor.http.ParanamerNameProvider$Proxy$_$$_WeldClientProxy.parametersFor(Unknown Source)
at br.com.caelum.vraptor.http.route.DefaultTypeFinder.getParameterTypes(DefaultTypeFinder.java:55)
at br.com.caelum.vraptor.http.route.DefaultTypeFinder$Proxy$_$$_WeldClientProxy.getParameterTypes(Unknown Source)
at br.com.caelum.vraptor.http.route.DefaultRouteBuilder.addParametersInfo(DefaultRouteBuilder.java:196)
at br.com.caelum.vraptor.http.route.DefaultRouteBuilder.is(DefaultRouteBuilder.java:185)
at br.com.caelum.vraptor.http.route.PathAnnotationRoutesParser.registerRulesFor(PathAnnotationRoutesParser.java:118)
at br.com.caelum.vraptor.http.route.PathAnnotationRoutesParser.rulesFor(PathAnnotationRoutesParser.java:92)
at br.com.caelum.vraptor.http.route.PathAnnotationRoutesParser$Proxy$_$$_WeldClientProxy.rulesFor(Unknown Source)
at br.com.caelum.vraptor.ioc.ControllerHandler.handle(ControllerHandler.java:66)
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Executable;
import javax.annotation.Priority;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Alternative;
import javax.interceptor.Interceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import br.com.caelum.vraptor.http.Parameter;
import br.com.caelum.vraptor.http.ParameterNameProvider;
@ApplicationScoped
@Alternative
@Priority(Interceptor.Priority.APPLICATION + 10)
public class JavaParameterNameProvider implements ParameterNameProvider {
private static final Logger logger = LoggerFactory.getLogger(JavaParameterNameProvider.class);
@Override
public Parameter[] parametersFor(AccessibleObject executable) {
logger.debug("looking for parameter names {}", executable);
java.lang.reflect.Parameter[] params = ((Executable) executable).getParameters();
Parameter[] out = new Parameter[params.length];
for (int i = 0; i < params.length; i++) {
if (!params[i].isNamePresent()) {
throw new IllegalStateException("No parameters found: " + executable);
}
out[i] = new Parameter(i, params[i].getName(), executable);
}
return out;
}
}
fiz o teste e a aplicação rodou, mas dava erro em qualquer link que clicava… verifiquei mais a fundo e os parâmetros estavam vindo com nomes do tipo: “arg0, arg1”… logicamente não iria funcionar, mas eu coloquei o parâmetro (-parameters) nas “Opções adicionais do Compilador” do Netbeans… comentando as lambdas tudo roda bem…
No site do paranamer diz que não é necessário usá-lo a não ser que se queira retro compatibilidade com Java 7 e Java 6…
alguém tem uma ideia do que possa ser e como resolver?
Não! Se eu coloco as lambdas e deixo o paranamer nas libs… ele dá esse erro ai de cima no stacktrace… faz sentido se o paranamer ainda não estiver preparado para a sintaxe das lambdas…
me foi sugerido então usar a classe JavaParameterNameProvider para substituir o paranamer (que é desnecessário caso se use java 8 e não se necessite retrocompatibilidade) e adicionar o parâmetro de compilação -parameters… fiz isso, removi a lib do paranamer das libs, coloquei a classe acima (JavaParameterNameProvider) no projeto e adicionei o parâmetro de compilação, mas para a minha surpresa, os nomes dos parâmetros não estavam como deveriam… estavam no seguinte formato: “arg0”, “arg1”, etc…
baixei aquelas classes de exemplo da oracle (MethodParameterSpy e ExampleMethods) e compile com “javac -parameters” e os nomes dos parâmetros foram pegos certinho…
então não sei se o netbeans tá ignorando meu parâmetro de compilação, se a classe que coloquei no projeto está deixando de fazer alguma coisa, se é preciso fazer mais alguma para que isso funciona, não sei…
Fala Lucas, seguinte, percebi uma coisa estranha agora, talvez te ajuda a entender o problema…
Quando tiro a classe JavaParameterNameProvider, coloco a lib do paranamer no projeto, coloco alguma lambda numa classe fora dos controllers (classe utilitárias, classes de persistência, etc) ele implanta e executa o projeto normalmente, inclusive o código da lambda… mas se a lambda tiver dentro de alguma das classes do controller nem implanta o projeto…
Fala Lucas, então… fiz o debug lá… ele dá pau na seguinte linha da classe PathAnnotationRoutesParser:
rule.is(baseType, javaMethod);
linha 118, para ser mais preciso…
só acontece no controller que tem a lambda, mas não especificamente no método que tem a lambda…
indo um pouco mais a fundo… o estouro se dá em:
[code]
// 1) Classe: PathAnnotationRoutesParser
// linha 118 rule.is(baseType, javaMethod);
// 3) Classe: DefaultTypeFinder
// Linha 56
Parameter[] parametersFor = provider.parametersFor(method);
[/code] daí o debug não passa…
ajudou um pouco? mais algum teste?
Bom dia Lucas, não sei se entendi muito bem sua pergunta…
mas fazendo o debug novamente, fiquei acompanhando as classes que passavam por esse método (registerRulesFor)… no momento em que a aplicação pendura ele está trabalhando com a classe que tem a lambda (LoginController)… nesse momento não importa se é o método que tem a lambda ou qualquer outro da classe… até pendurar não passa nenhuma classe maluca por ali, só os controllers…
na saída da aplicação não sai erro algum… no log do tomcat sai o erro descrito no primeiro post… e na saida do depurador sai apenas:
para você entender melhor o que estou fazendo coloquei uns souts:
é com essa classe que a aplicação aborta a implantação…
OBS: o método check não é o que contém a lambda… ele dá erro no primeiro método encontrado, independente de ter lambda lá ou não…