2012-02-29 39 views
18

Tôi đang gặp lỗi trong trình biên dịch Java, nơi thứ tự các tệp được gửi để biên dịch có thể khiến mã không biên dịch. Tôi đã khoan xuống mã để cô lập số lượng nhỏ nhất của mã tôi có thể để tái tạo các vấn đề, kết quả là three source files (mỗi lớp 1).Giải pháp khắc phục lỗi biên dịch javac trong maven

public interface ActionSpec { 
    public abstract int run(String param); 
} 


public enum Actions implements ActionSpec { 
    SKIP { 
     public int run(String d) { 
      return 0; 
     } 
    }; 
} 

public class Program { 

    public static void main(String[] args) { 
     Actions.SKIP.run("hello"); 
    } 
} 

Sự cố có thể tái tạo bằng cách có đối số javac theo thứ tự cụ thể. Nói tóm lại, để thành công, các lớp Hoạt động luôn luôn phải được biên soạn trước lớp Chương trình trong đó sử dụng nó, nếu không javac chỉ thất bại trong việc đối phó với nó một cách lành mạnh:

# this case fails 
echo "Trying order: javac Program.java Actions.java ActionSpec.java" 
rm *class 
javac -verbose Program.java Actions.java ActionSpec.java 

# this case fails 
#rm *class 
#javac Program.java Actions.java ActionSpec.java 

# this case fails 
#rm *class 
#javac ActionSpec.java Program.java Actions.java 

# this case succeeds 
#rm *class 
#javac ActionSpec.java Actions.java Program.java 

# this case succeeds 
#rm *class 
#javac Actions.java ActionSpec.java Program.java 

# this case succeeds 
#rm *class 
#javac Actions.java Program.java ActionSpec.java 

Các lỗi biên dịch, khi nó xảy ra , luôn luôn giống nhau - phương thức chạy trên các cá thể Action enum không thể được tìm thấy, mặc dù chúng đều thực hiện một giao diện có phương thức chạy đó.

Program.java:6: cannot find symbol 
symbol : method run(java.lang.String) 
location: class problem.Actions 
     Actions.SKIP.run("hello"); 

Lỗi này có vẻ liên quan đến this one reported on Oracle's site. Tôi đang sử dụng javac 1.6.0_29, trên mac os x 10.7.2 x86_64, nhưng cũng đã sao chép nó trên Linux.

Vấn đề này trở nên rõ ràng khi tôi đang sử dụng Maven để xây dựng và dường như không có bất kỳ kiểm soát nào đối với thứ tự biên dịch. Vì vậy, tôi đang tìm một workaround hoặc lực lượng maven để biên dịch các tập tin theo thứ tự như vậy là để tránh lỗi trình biên dịch này, hoặc fiddle với cờ biên dịch (hoặc một cái gì đó giống như nó) để tránh nó. Các vấn đề cây trồng lên trên máy trạm và trong môi trường hội nhập liên tục như nhau, vì vậy nó sẽ phải làm việc trên bảng. Bất kỳ đề xuất?

EDIT: Chỉ cần thử cách giải quyết sau, mặc dù chỉ đơn thuần chỉ định enum được đề cập đến một biến với loại giao diện mà nó triển khai, gây ngạc nhiên cho lỗi biến mất.

public class Program { 

    public static void main(String[] args) { 
     ActionSpec a = Actions.SKIP; 
     a.run("hello"); 
    } 
} 

Vẫn quan tâm đến ý kiến ​​của người khác.

+0

Không ngạc nhiên khi việc giới thiệu 'ActionSpec' bắt đầu hoạt động. Có lẽ lỗi được giới hạn trong enum và những gì nó thực hiện. 'Import' cũng có thể hữu ích. –

+0

Bạn đã thử thêm phương thức 'abstract abstract int (String d);' vào enum chưa? –

+0

Không nên cần phải kể từ khi lớp enum thực hiện giao diện, và tất cả các trường hợp của nó chứa triển khai thực hiện của phương thức (hoặc khác enum sẽ không biên dịch). –

Trả lời

5

Tôi chơi xung quanh, và thấy rằng việc thêm dàn diễn viên đơn giản:

public static void main(String[] args) { 
    ((ActionSpec)Actions.SKIP).run("hello"); 
} 

giải quyết vấn đề này. Việc chuyển tham số này dưới dạng tham số phương thức làm giao diện cũng sẽ thực hiện thủ thuật

+0

Đồng ý, điều này tương tự như cách giải quyết mà tôi đã khám phá và là giải pháp đơn giản nhất. –

0

Đây là cách tôi sẽ làm điều đó:

  • Chuyển giao diện ActionSpec cho một dự án Maven. Chúng tôi thường có các giao diện và các lớp miền phổ biến trong dự án của riêng họ, ví dụ: foo-service-specs.
  • Giữ các lớp khác trong dự án triển khai, ví dụ: foo-service-impl.
  • Bao gồm dự án foo-service-specs dưới dạng phụ thuộc trong foo-service-impl.

Bằng cách này, bạn có thể đảm bảo rằng thứ tự biên dịch đang hoạt động và cũng nên hoạt động để tích hợp liên tục.

+0

Vẫn không đảm bảo rằng Hành động biên dịch trước Chương trình, đó là mấu chốt của vấn đề. –

0

Thử nhiều lần thực hiện plugin trình biên dịch. Sử dụng default-compile làm ID thực thi đầu tiên thêm cấu hình mới vào thực thi trình biên dịch mặc định của Maven. Sử dụng các phần tử cấu hình <includes/> trong thực thi mặc định để biên dịch các enums trước. Đối với lần thực thi thứ hai, bạn sử dụng kết hợp của <includes><excludes>, trong đó <includes> sẽ là tất cả mã của bạn và loại trừ sẽ là các enums đã được biên soạn.

Tôi nghĩ rằng điều này sẽ làm việc cho chương trình ví dụ của bạn nhưng tôi đã không kiểm tra nó. Tôi đã thử nghiệm một cái gì đó tương tự như trước với Maven 3 và nó đã làm việc tốt.

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-compiler-plugin</artifactId> 
    <version>2.3.2</version> 
    <configuration> 
     <source>1.6</source> 
     <target>1.6</target> 
    </configuration> 
    <executions> 
     <execution> 
      <id>default-compile</id> 
      <goals><goal>compile</goal></goals> 
      <configuration> 
       <includes> 
        <include>**/Actions.*</include> 
       </includes> 
      </configuration> 
     </execution> 
     <execution> 
      <id>second</id> 
      <goals><goal>compile</goal></goals> 
      <configuration> 
       <includes> 
        <include>**/*</include> 
       </includes> 
       <excludes> 
        <exclude>**/Actions.*</exclude> 
       </excludes> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 
0

Chúng tôi đã gặp phải vấn đề tương tự. Nhiều hành của các plugin maven compiler làm việc cho chúng tôi ...

4

Đó là lỗi được báo cáo trong http://bugs.sun.com/view_bug.do?bug_id=6724345

Cách giải quyết đề nghị nên làm việc nếu bạn vẫn đang sử dụng Java 6 biên dịch. Lỗi này được sửa trong Java 7.

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