2010-09-27 27 views
47

Tôi đã tạo ra một dự án maven tối thiểu với một mô-đun con duy nhất trong helios eclipse.this.getClass(). GetClassLoader(). GetResource ("...") và NullPointerException

Trong thư mục src/test/resources tôi đã đặt một tệp "install.xml". Trong thư mục src/kiểm tra/java Tôi đã tạo ra một gói phần mềm duy nhất với một lớp duy nhất có quyền này:

@Test 
    public void doit() throws Exception { 
    URL url = this.getClass().getClassLoader().getResource("install.xml"); 
    System.out.println(url.getPath()); 

    } 

nhưng khi tôi chạy mã như một đơn vị kiểm tra JUnit 4 tôi chỉ nhận được một NullPointerException. Điều này đã làm việc tốt một triệu lần trước. Bất kỳ ý tưởng?

Tôi đã theo hướng dẫn này:

http://www.fuyun.org/2009/11/how-to-read-input-files-in-maven-junit/

nhưng vẫn nhận được lỗi tương tự.

Trả lời

73

Khi bạn sử dụng

this.getClass().getResource("myFile.ext") 

getResource sẽ cố gắng để tìm thấy tài nguyên liên quan đến các gói. Nếu bạn sử dụng:

this.getClass().getResource("/myFile.ext") 

getResource sẽ đối xử với nó như một đường dẫn tuyệt đối và chỉ cần gọi classloader như bạn sẽ có nếu bạn muốn thực hiện.

this.getClass().getClassLoader().getResource("myFile.ext") 

Lý do bạn không thể sử dụng một / hàng đầu trong đường dẫn ClassLoader là bởi vì tất cả ClassLoader đường dẫn là tuyệt đối và do đó / không phải là một nhân vật đầu tiên có giá trị trong con đường.

+0

Nó bật ra rằng cha mẹ pom nhóm của tôi sử dụng chỉ bao gồm * .xml và * .properties. Bây giờ ... tại sao điều này chạy trên máy trạm của tôi, tôi không chắc chắn. Tôi thậm chí còn nhìn vào repo maven địa phương của tôi để xác minh rằng nó có cùng một pom như những gì đã được ra trên hộp linux. – AmishDave

+2

Xin chào @AmishDave, câu hỏi tiếp theo của bạn (nếu bạn vẫn cần câu trả lời) nên được đăng dưới dạng câu hỏi mới. Vui lòng liên kết lại câu hỏi này và/hoặc câu trả lời này, nhưng có một câu hỏi tiếp theo trong câu trả lời không phải là cách thông thường cách Stack Overflow hoạt động. Cảm ơn! :-) –

16

Nó phải là getResource("/install.xml");

Các tên tài nguyên có liên quan đến nơi getClass() lớp cư trú, ví dụ nếu thử nghiệm của bạn là org/example/foo/MyTest.class thì getResource("install.xml") sẽ xem trong org/example/foo/install.xml.

Nếu install.xml của bạn ở số src/test/resources, nó nằm trong thư mục gốc của đường dẫn lớp, do đó bạn cần phải thêm tên tài nguyên với /.

Ngoài ra, nếu nó chỉ hoạt động đôi khi, thì có thể vì Eclipse đã làm sạch thư mục đầu ra (ví dụ: target/test-classes) và tài nguyên chỉ đơn giản là thiếu từ đường dẫn lớp thời gian chạy. Xác minh rằng sử dụng khung nhìn Navigator của Eclipse thay vì trình thám hiểm Gói. Nếu các tệp bị thiếu, hãy chạy mục tiêu mvn package.

+1

Tôi cũng đã thử: this.getClass(). GetClassLoader(). GetResource ("/ install.xml"); không giúp đỡ (Tất cả dự án khác của tôi đọc tài nguyên không sử dụng tiền tố "/" và chúng hoạt động tốt). Tôi cũng đã cố gắng chạy mvn sạch cài đặt (cả từ commandline và từ eclipse) trên cha mẹ và con nhưng vẫn còn cùng một vấn đề. Khi tôi kiểm tra thư mục con: target/test-classes trong khung nhìn navigator rỗng của nó - hãy đoán điều này là xấu. – u123

+0

vâng, điều đó thật tệ. Đăng một phần của pom của bạn, nơi bạn chỉ định (nếu có) các thẻ . Có lẽ bạn đang thực hiện một số hoặc trong đó? mvn cài đặt chắc chắn nên sao chép các tập tin tài nguyên của bạn để các lớp resp. thư mục lớp học thử nghiệm. Bạn đang sử dụng M2Eclipse? – mhaller

+0

Tôi chưa chạm vào bất kỳ câu lệnh bao gồm/loại trừ nào. Tôi thấy điều này: https://issues.sonatype.org/browse/MNGECLIPSE-823 có thể giải quyết vấn đề này. Tôi đã tạo một dự án mới và nó hoạt động trở lại. – u123

29

Tul,

  • Khi bạn sử dụng .getClass().getResource(fileName) nó xem xét vị trí của fileName là cùng một vị trí của của lớp gọi.
  • Khi bạn sử dụng .getClass().getClassLoader().getResource(fileName) nó xem xét vị trí của tệpName là thư mục gốc - nói cách khác là bin thư mục.

Nguồn:

package Sound; 
public class ResourceTest { 
    public static void main(String[] args) { 
     String fileName = "Kalimba.mp3"; 
     System.out.println(fileName); 
     System.out.println(new ResourceTest().getClass().getResource(fileName)); 
     System.out.println(new ResourceTest().getClass().getClassLoader().getResource(fileName)); 
    } 
} 

Output:

Kalimba.mp3 
file:/C:/Users/User/Workspaces/MyEclipse%208.5/JMplayer/bin/Sound/Kalimba.mp3 
file:/C:/Users/User/Workspaces/MyEclipse%208.5/JMplayer/bin/Kalimba.mp3 
+0

Tôi nên làm gì để có tài nguyên Maven từ thư mục tài nguyên trong thùng rác? Tôi thấy rằng ngay cả khi tôi chạy Maven cài đặt, chúng không xuất hiện ở đó. Nhưng có lẽ tôi hiểu điều gì đó chỉ sai :) – Line

3

tôi đã cùng một vấn đề với các điều kiện sau:

  • Các tập tin tài nguyên đang trong gói giống như tệp nguồn java, trong thư mục nguồn java (src/test/java).
  • Tôi xây dựng dự án với maven trên dòng lệnh và bản dựng không thành công trên các thử nghiệm với NullPointerException.
  • Xây dựng dòng lệnh không sao chép các tệp tài nguyên vào thư mục test-classes, giải thích lỗi xây dựng.
  • Khi chuyển sang nhật thực sau khi tạo dòng lệnh và chạy lại các kiểm tra trong nhật thực, tôi cũng có NullPointerException trong nhật thực.
  • Khi tôi làm sạch dự án (đã xóa nội dung của thư mục đích) và xây dựng lại dự án trong Eclipse, thử nghiệm đã chạy đúng. Điều này giải thích lý do tại sao nó chạy khi bạn bắt đầu với một dự án sạch sẽ.

Tôi đã sửa lỗi này bằng cách đặt các tệp tài nguyên trong thư mục tài nguyên trong thử nghiệm: src/test/resources sử dụng cấu trúc gói giống như lớp nguồn.

BTW Tôi đã sử dụng getClass().getResource(...)

0

Tôi gặp vấn đề tương tự khi làm việc với dự án có Maven. đây làm thế nào tôi cố định nó: Tôi chỉ cần đặt các nguồn (hình ảnh, nhạc và các chất liệu khác) trong thư mục nguồn:

src/main/resources 

Tôi tạo ra cấu trúc tương tự cho các gói trong thư mục nguồn lực quá. Ví dụ:

Nếu lớp học của tôi là trên

com.package1.main 

Trong thư mục nguồn tôi đặt một gói có cùng tên

com.package1.main 

Vì vậy, tôi sử dụng

getClass().getResource("resource.png"); 
1

tôi nghĩ rằng tôi đã gặp phải vấn đề tương tự như của bạn. Tôi tạo ra một dự án mvn đơn giản và sử dụng "mvn eclipse: eclipse" để thiết lập một dự án eclipse.

Ví dụ: tệp nguồn "Router.java" của tôi nằm trong "java/main/org/jhoh/mvc". Và Router.java muốn đọc tệp "tuyến đường" nằm trong "java/main/org/jhoh/mvc/resources"

Tôi chạy "Router.java" trong nhật thực và bảng điều khiển của eclipse có NullPointerExeption. Tôi đặt pom.xml với cài đặt này để tạo tất cả các tệp java bytecode * .class trong thư mục xây dựng.

<build> 
    <defaultGoal>package</defaultGoal> 
    <directory>${basedir}/build</directory> 
<build> 

Tôi đã đi đến thư mục "build/classes/org/jhoh/mvc/resources" và không có "tuyến đường".Eclipse DID NOT bản sao "đường" để "xây dựng/classes/org/jhoh/MVC/tài nguyên"

Tôi nghĩ rằng bạn có thể sao chép "install.xml" của bạn để thư mục * .class bytecode của bạn, KHÔNG trong thư mục mã nguồn của bạn.

2

Khi nhật thực chạy trường hợp kiểm tra, nó sẽ tìm tệp trong mục tiêu/lớp không phải là src/test/resources. Khi tài nguyên được lưu eclipse nên sao chép nó từ src/test/resources đến target/classes nếu nó đã thay đổi nhưng nếu vì một lý do nào đó điều này đã không xảy ra thì bạn sẽ nhận được lỗi này. Kiểm tra xem tệp có tồn tại trong mục tiêu/lớp để xem đây có phải là vấn đề không.

0

Một điều khác để nhìn vào mà giải quyết nó cho tôi:

Trong một dự án Eclipse/Maven, tôi đã có các lớp Java trong src/test/java trong đó tôi đã sử dụng mô hình this.getClass().getResource("someFile.ext"); để tìm kiếm các nguồn lực trong src/test/resources nơi có tài nguyên tệp nằm trong cùng một vị trí gói trong thư mục nguồn tài nguyên vì lớp kiểm tra nằm trong thư mục nguồn thử nghiệm. Nó vẫn không tìm được chúng.

Nhấp chuột phải vào thư mục nguồn src/test/resources, Đường dẫn xây dựng, sau đó "định cấu hình bộ lọc bao gồm/loại trừ"; Tôi đã thêm bộ lọc bao gồm mới **/*.ext để đảm bảo tệp của tôi không bị xóa; kiểm tra của tôi bây giờ có thể tìm thấy các tập tin tài nguyên của họ.

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