2010-06-22 42 views
5

Tôi muốn nhập một lớp mà tôi đã viết trong một thư mục bên ngoài, ví dụ: Lớp học của tôi Example.java mà nằm ở c:\class\Example.java để kịch bản của tôi như sử dụngScripting java: import class từ một tập tin bên ngoài

var importedClass = new JavaImporter("c:\\class\\Example.java"); 

hoặc

importClass("c:\\class\\Example.java"); 

này là trong một kịch bản cho ScriptEngine tê giác
làm thế nào tôi có thể làm điều đó ???

+1

Bất kỳ lý do nào bạn không thể sử dụng classpath? –

+0

Bạn có muốn nhập một lớp Java trong JavaScript sẽ được chạy bằng cách sử dụng tê giác không? Hay bạn muốn nhập một lớp JavaScript trong Java bằng cách sử dụng tê giác? –

+0

Tôi muốn nhập một lớp Java trong một tệp JavaScript sẽ chạy bằng Rhino :) đây là số –

Trả lời

5

Tôi hiểu rằng bạn muốn:

  1. Biên soạn một nguồn Java tập tin
  2. tải mã biên soạn
  3. Sử dụng lớp kết quả trong một số hoạt Javascript

Gói javax.tools cung cấp một cơ chế biên dịch mã, mặc dù nếu bạn không chạy trong JDK, ToolProvider.getSystemJavaCompiler() sẽ trả về null và bạn sẽ phải dựa vào e cơ chế biên dịch khác (gọi trình biên dịch bên ngoài; nhúng trình biên dịch Eclipse; v.v.)

Java bytecode (.class nhị phân) có thể được tải khi chạy qua ClassLoader s.

Để các lớp được tải hiển thị cho công cụ tạo tập lệnh của bạn, bạn sẽ cần cung cấp chúng thông qua hàm tạo ScriptEngineManager(ClassLoader).


EDIT: dựa trên các yêu cầu

public class HelloWorld { 
    public void say() { 
    System.out.println("Hello, World!"); 
    } 
} 

Kịch bản này chỉ gọi sự phản chiếu Java API để tải và thuyết minh một lớp HelloWorld.class từ C:\foo\bin thư mục:

function classImport() { 
    var location = new java.net.URL('file:/C:/foo/bin/'); 
    var urlArray = java.lang.reflect.Array.newInstance(java.net.URL, 1); 
    urlArray[0] = location; 
    var classLoader = new java.net.URLClassLoader(urlArray); 
    return classLoader.loadClass("HelloWorld"); 
} 

var myClass = classImport(); 

for(var i=0; i<10; i++) { 
    myClass.getConstructor(null).newInstance(null).say(); 
} 

Có nhiều những cách tao nhã để làm điều này, tôi chắc chắn.

+0

Hãy tưởng tượng rằng tôi có một ứng dụng và tôi không muốn thay đổi, tất cả những gì tôi có thể thay đổi là Tệp Tập lệnh được tải trong ứng dụng. Vì vậy, nếu tôi muốn làm điều gì đó, tôi không thể làm điều đó trong mã Java của ứng dụng, nhưng chỉ trong tệp kịch bản lệnh, vì vậy, tôi muốn nhập một lớp bên ngoài dự án của tôi, được biên dịch và định vị ổ cứng của tôi. Hy vọng rằng tôi sẽ giải thích thêm: s thnx rất nhiều –

0

Nếu tôi hiểu chính xác bạn, những gì bạn đang thực sự cố gắng làm là tải các lớp Java để bạn có thể (có lẽ) tạo các cá thể, v.v. Thuật ngữ cho điều này là tải động không nhập.

Java cho phép bạn tải động các tệp bytecode (*.class) bằng phương pháp ClassLoader.loadClass(String). Có rất nhiều tài nguyên về chủ đề này; ví dụ. trang "Class Loading" từ hướng dẫn JNDI. Hãy chuẩn bị sẵn sàng dành thời gian suy nghĩ về chủ đề này. Đặc biệt, vì bạn đang cố tải một lớp không nằm trong classpath thông thường của ứng dụng, bạn sẽ cần phải tạo một trình nạp lớp mới để làm điều này. Javadocs cho lớp java.lang.ClassLoaderhere.

Mã nguồn Java không thể được tải trực tiếp, nhưng trước hết phải được biên dịch bằng trình biên dịch Java. Nếu bạn đang sử dụng một cài đặt JDK hiện đại, có thể gọi trình biên dịch Java lúc chạy. Nhưng cài đặt JRE không bao gồm trình biên dịch Java. Nếu nền tảng của bạn có trình biên dịch Java có sẵn khi chạy, bạn có thể truy cập nó thông qua phương thức tĩnh getSystemJavaCompiler() của lớp ToolProvider. Một lần nữa, việc gọi trình biên dịch Java từ bên trong một ứng dụng Java đang chạy là phức tạp.

+0

Thnx cho câu trả lời, Điều tôi muốn làm là thêm một lớp ví dụ MyClass.java mà tôi được biên dịch sang MyClass.class vì vậy tôi muốn nhập MyClass vào ổ cứng của mình, không phải trong các gói của dự án của tôi, và bên trong tệp tập lệnh: ví dụ: importClass ("D: \\ SVN_KC \\ KP \\ trunk \\ Protos \\ ScriptEngine \\ scripts \\ Exemple.class "); –

1

Tôi sẽ đặt câu hỏi tại sao thực hiện việc này.

Các giải pháp được liệt kê tại đây sẽ hoạt động. Vấn đề sẽ là rằng:

  1. Bạn sẽ có một gom góp giải pháp với sự phản ánh rằng sẽ khó để gỡ rối.
  2. Khách hàng của bạn có đồng ý với mã vá được tải tại Thời gian chạy không? Mọi nơi tôi đã làm việc thì không.
+0

Điều cần làm là cho phép khách hàng sửa đổi tệp tập lệnh mà không cần chạm vào ứng dụng. Tôi nghĩ rằng bằng cách sử dụng nội tâm như nó đã được nói trong tập tin kịch bản sẽ làm việc thnx rất nhiều –

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