2015-05-25 34 views
7

Có thể sử dụng các chức năng gói Kotlin và các thuộc tính gói trong các nguồn khác nhau không? Khi tôi cố gắng làm như vậy, tôi đã ném NoSuchMethodError.Kotlin: java.lang.NoSuchMethodError trong các thử nghiệm


Ví dụ

Tôi có dự án với mã Kotlin và hai sourcesets trong nó, maintest Gradle. Trong main, tôi có mã sau đây trong một trong những tập tin:

package ru.ifmo.ctddev.igushkin.dkvs 
... 
public val payloadSplitter: String = " ### " 

Trong test tôi thử truy cập payloadSplitter với đoạn mã sau:

package ru.ifmo.ctddev.igushkin.dkvs 
... 
public class MessageTests { 
    ... 
    test fun testParsing() { 
     ... 
     checkParseAndToString("p1b 345 ${payloadSplitter} set a b c") 
    } 
    ... 
} 

Và chính xác trong dòng đầu tiên nơi payloadSplitter là được truy cập, vào thời gian chạy, tôi nhận được

java.lang.NoSuchMethodError: ru.ifmo.ctddev.igushkin.dkvs.DkvsPackage.getPayloadSplitter()Ljava/lang/String; 

Các biến và hàm toàn cầu khác cũng không thể truy cập được trong test với cùng lỗi.


UPD Kotlin đội giải thích vấn đề này và thông báo việc sửa chữa here.

+1

Bạn có bất kỳ chức năng/thuộc tính cấp cao nhất trong gói ru.ifmo.ctddev.igushkin.dkvs trong các thử nghiệm không? –

+0

Làm thế nào để bạn chạy thử nghiệm? Bạn có thể đăng cấu hình gradle của bạn? Có vẻ như gói thử nghiệm được biên dịch dựa trên gói chính nhưng được chạy mà không có gói đó. –

+0

@SalomonBRYS, https://github.com/h0tk3y/dkvs/blob/master/build.gradle - đây rồi. – hotkey

Trả lời

5

Đối với các thuộc tính và phương thức bên ngoài lớp, Kotlin tạo một lớp java có tên $ {packagename} Gói với các thuộc tính và phương thức được thực hiện như các phương thức và biến tĩnh. Với nhiều bộ nguồn, lớp java sẽ được tạo hai lần, một lần cho mỗi bộ nguồn. Vấn đề của bạn là bộ "lớp gói" của bộ nguồn thử nghiệm đang ẩn lớp được biên dịch trong bộ nguồn chính.

Như đã đề cập trong các chú thích ở trên, tránh có bất kỳ thuộc tính hoặc phương pháp cấp cao nhất trong bộ nguồn thử nghiệm để ngăn trình biên dịch Kotlin tạo lớp gói này trong thư mục kết quả thử nghiệm.

+0

Cảm ơn. Có một cách giải quyết khác theo sau những gì bạn nói, tôi đã đăng nó như một câu trả lời khác. – hotkey

+0

Một lưu ý khác về giải pháp này; ít nhất là ở Gradle, bạn cần phải chạy một bản xây dựng sạch sẽ, hoặc người thử nghiệm vẫn sẽ tìm thấy lớp Package được tạo ra. –

1

Ngoài những gì đã được đề xuất trước đó, tôi đã tìm thấy cách giải quyết khác: nếu bạn cần các hàm hoặc thuộc tính cấp gói trong test chỉ cần di chuyển các thử nghiệm sang gói khác, ví dụ: trong các nguồn thử nghiệm của bạn:

package ru.ifmo.ctddev.igushkin.dkvs.tests 

và sau đó làm

import ru.ifmo.ctddev.igushkin.dkvs.* 

đó là tất cả mọi thứ từ gói chính của bạn. Điều này sẽ làm cho trình biên dịch Kotlin tạo ra hai lớp Package không xung đột, do đó cả hai có thể có các thành viên toàn cầu.

Các vấn đề liên quan