O proxy Clojure 1.2.1 / 1.3 / 1.4 'gerado no tempo de execução Grails 2.0.0 falha. 1.2.0 está bem

103

Estou trabalhando na extensão do plugin Grails Clojure em Grails 2.0.0 (e 2.1.0-SNAPSHOT) e queria atualizá-lo para Clojure 1.3.0 e adicionar clojure.tools.logging .

Clojure inicia uma excepção durante a compilação de uma procuração de um ByteArrayOutputStreamem clojure.tools.loggingfunção de log-stream 's:

ClassCastException: clojure.asm.Type cannot be cast to clojure.lang.IFn

( https://gist.github.com/a6ae681c37091a3d2379 )

Eu fui, removi clojure.tools.logginge escrevi um proxy simplificado de Object:

(proxy [java.lang.Object] [] (toString [] "proxy's toString"))

e também lançou essa mesma ClassCastExceptionmensagem.

Tentei imprimir um macroexpand-1 do proxy e obtive a mesma coisa.

Eu reverti para o Clojure 1.2.0 e o proxy funcionou bem novamente.

Tentei uma série de encarnações do 1.4.0 e eles exibem o mesmo comportamento do 1.3.0. 1.2.1 também lança algum tipo de exceção, mas estou tentando atingir 1.3.0, então não gastei muito tempo com isso.

O rastreamento de pilha aponta para a função 'gen-method definida em uma das formas let de generate-proxyin core_proxy.clj.

Eu adicionei um pouco de println's por ali para ver se conseguia entender o que estava acontecendo. Talvez esta próxima declaração denuncie um grande mal-entendido do leitor da minha parte, mas simplesmente adicionar aqueles printlns mudou o comportamento do tempo de compilação de uma forma que eu totalmente não esperava. O local e o tipo de exceção mudaram completamente, embora todos os testes Clojure em mvn packagecontinuem a passar.

Por exemplo, apenas adicionar um único printlnao gen-método antes de começar a gerar bytecode fez com que Clojure lançasse

ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Class

( https://gist.github.com/5a7a40929a6c4a104bd5 )

Já vi vários outros erros, dependendo de onde coloquei o println(s), mas este é o mais comum.

Obviamente, alguns aspectos de Grails e Clojure não estão se encaixando corretamente aqui, mas não estou vendo a conexão. No começo eu suspeitei de incompatibilidade ASM, mas como Clojure tem seu próprio namespace ASM, não consigo ver que esse seja o problema. Mas talvez eu esteja errado, eu estive olhando clojure.lang.Compiler, procuração e gerar-proxy para os dias agora a tentar chegar a este trabalho e eu praticamente parou de fazer avançar o progresso porque eu funcionar fora do vapor :(

Peço desculpas pela falta de links. Você pode copiar e colar abaixo:

Grails Clojure - github.com/grails-plugins/grails-clojure

Clojure Tools Logging - github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging.clj linha 133 é o 'proxy

John Courtland
fonte
4
Fiz mais alguns testes e estou quase convencido de que é algo no Grails 2.0 que está destruindo algo do qual o Clojure 1.3 depende. Eu testei o exemplo de código mais simples que posso conceber no Grails 1.3.7, Groovy 1.8.4 (que é o que Grails 2.0 usa) e Groovy 1.8.5 (o mais recente) e todos funcionam.
John Courtland
3
Isso poderia ser um problema ClassLoader?
Jeremy

Respostas:

4

Eu encontrei um problema chamado CLJ-944em clojure.org . Lá você pode encontrar uma solução para o ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Classproblema

O problema é:

que o compilador injeta uma conversão incorreta em clojure.lang.PersistentHashMap. Nesse caso, ele provavelmente deve ser convertido em um clojure.lang.Associative, a interface comum mais alta que possui o método .containsKey.

Patch 1 - 0001-Fix-for-CLJ-944.patch

Patch 2 - 0002-Fix-for-CLJ-944.patch

Espero que ajude.

Sentencio
fonte