2013-01-21 14 views
5

Próbuję przenieść kod z przykładów Dropwizard z java na groovy.Nie można używać zmiennych zdefiniowanych w klasach wewnątrz groovenych adnotacji.

widzę, że w języku Java, można użyć poniższy kod, bez żadnych problemów:

package com.example.helloworld; 
import javax.ws.rs.*; 
import javax.ws.rs.core.MediaType; 

@Produces(MediaType.APPLICATION_JSON) 
public class HelloWorldService{ 

} 

Jednak z groovy kompilatora (oba 1.8 i 2.0.6), klasa nie skompilować z noClassFoundException wokół MediaType.APPLICATION_JSON

Jeśli zmienić ten kod do korzystania z rzeczywistą wartość ciągu

@Produces('application/json') 
public class HelloWorldService{ 

} 

wszystko działa idealnie.

Czy są jakieś różnice między sposobem, w jaki groove rozwiązuje adnotacje, a sposobem, w jaki robi to java?

Dla kompletności, jest częścią projektu Gradle i tu jest moje build.gradle (plik idzie pod src/Groovy/com/example/helloworld)

apply plugin: 'groovy' 

// Set our project variables 
project.ext { 
    dropwizardVersion = '0.6.1' 
} 

repositories { 
    mavenCentral() 
} 

dependencies { 
    compile group: 'com.yammer.dropwizard', name: 'dropwizard-core', version: dropwizardVersion 
    groovy group: 'org.codehaus.groovy', name: 'groovy-all', version: '1.8.7' 
} 

Błąd kompilacji:

Spowodowany przez: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.sun.ws.rs.ext.RuntimeDelegateImpl ... 17 więcej Spowodowany przez: java.lang.ClassNotFoundException: com. sun.ws.rs.ext.RuntimeDe legateImpl w org.gradle.api.internal.tasks.compile.TransformingClassLoader.findClass (TransformingClassLoader.java:47)

+0

Czy działa z '@Produces (javax.ws.rs.core.MediaType.APPLICATION_JSON)' –

+0

Nie, to nie - ale błąd sprawia, że ​​myślę, że może to być coś bardziej stopniowego niż groovy rzecz –

+0

wydaje się być gradle błąd, ponieważ jestem w stanie skompilować samething przy użyciu groovy-eclipse i maven. –

Odpowiedz

6

problem jest spowodowany przez nieszczęśliwego ograniczenia Dynamikę kompilatora, a mianowicie to, że wykorzystuje refleksji dostęp do klas na ścieżce klasy kompilacji. To z kolei może spowodować załadowanie innych klas, które mogą nie być dostępne w ścieżce klasy kompilacji. Zazwyczaj (ale nie zawsze) są to zależności środowiska wykonawczego.

W konkretnym przypadku, Groovy ładunki kompilatora javax.ws.rs.core.MediaType poprzez odbicie, co ostatecznie skutkuje com.sun.ws.rs.ext.RuntimeDelegateImpl ładowany poprzez Class.forName (uruchamiane za pomocą statycznego inicjatora), który nie znajduje się na ścieżce klasy kompilacji. Rozwiązaniem jest umieszczenie tej klasy na ścieżce klasy kompilacji. (W dłuższej perspektywie rozwiązaniem jest naprawienie autonomicznego kompilatora Groovy, aby nie używał refleksji, az tego, co wiem, jest już w kolejce.) Jeśli przejściowe zależności modułu nie stanowią problemu, najprostszy sposób na osiągnięcie tego jest:

dependencies { 
    compile "com.sun.jersey:jersey-client:1.15" 
} 

podejrzewam, że kompilator Eclipse Groovy nie ma tego problemu, ponieważ nie używa odbicie na dostęp do ścieżki klasy kompilacji. Spodziewam się, że GMaven wyleci jak Gradle, chyba że jest skonfigurowany do używania kompilatora Eclipse (który nie jest obecnie obsługiwany przez Gradle).

Powiązane problemy