2012-01-03 32 views
11

Tôi đang sử dụng JBoss 7 (tải phụ thuộc đã được thay đổi trong phiên bản này). Ứng dụng chiến tranh của tôi tải lên các lọ máy chủ và cần phải sử dụng các lớp bên trong chúng, nhưng nó được ClassNotFoundException. Vì vậy, tôi không thể tìm cách thêm phụ thuộc vào các mô-đun vào động - MANIFEST.MF, jboss-deployment-structure.xml là cách tĩnh để thực hiện việc này.JBoss 7: cách nạp năng động bình

+1

Bạn đề cập đến tải phụ thuộc đã được thay đổi cho JBoss 7. Bạn đã làm điều này bằng cách sử dụng phiên bản trước của JBoss? Bạn có thể mô tả cách tiếp cận trước đây của bạn không? – GargantuChet

+0

Tôi cho rằng [tài liệu này] (https://community.jboss.org/wiki/ModuleCompatibleClassloadingGuide) có thể hữu ích – higuaro

Trả lời

5

Chỉ cần đọc lại câu hỏi để đảm bảo câu hỏi chính xác;

Bạn muốn có thể tải tệp jar tùy ý lên máy chủ và sau đó sử dụng các lớp/tài nguyên được chứa trong JVM? Không cần khởi động lại JVM và/hoặc chỉnh sửa mã nguồn của cấu hình của bạn.

Nếu đúng như vậy, bạn nên tải bình vào bộ nạp lớp (chuỗi trình nạp lớp hiện tại của bạn nếu cần) và sau đó tải lớp từ đó.

Giả sử bạn lưu trữ các file jar vật lý trên máy chủ bạn có thể ví dụ như làm một cái gì đó như:

public static Class<?> loadClass(String className, String jarFileLocation) 
     throws MalformedURLException, ClassNotFoundException { 
    URL jarUrl = new File(jarFileLocation).toURI().toURL(); 
    ClassLoader classLoader = new URLClassLoader(new URL[] {jarUrl }, MyClass.class.getClassLoader()); 
    return classLoader.loadClass(className); 
} 

public static Object executeMethodOndClass(String methodName, Class<?>[] parameterTypes, 
               Object[] parameters, String className, String jarFileLocation) 
     throws MalformedURLException, ClassNotFoundException, IllegalAccessException, InstantiationException, 
     NoSuchMethodException, InvocationTargetException { 
    Class<?> loadedClass = loadClass(className, jarFileLocation); 
    Method method = loadedClass.getMethod(methodName, parameterTypes); 
    Object instance = loadedClass.newInstance(); 
    return method.invoke(instance, parameters); 
} 

Ps. đây là mã thô, tôi thậm chí không biên dịch hay kiểm tra nó; nó nên công việc, nhưng không có gì nhiều hơn sau đó và có cơ hội tôi bỏ qua một cái gì đó hoặc thực hiện một lỗi đánh máy ;-)

Pps. cho phép các tệp jar tùy chỉnh được tải lên và các lớp từ nó được thực hiện sẽ mang lại một số rủi ro (bảo mật) với nó.

+0

Tôi thích câu trả lời này nhưng không giải quyết được câu hỏi. Sự khác biệt cuối cùng giữa việc thiết lập một phụ thuộc trong jboss thông qua manfiest/jboss-deployment-structure.xml là nó ngầm làm cho tất cả các lớp mà bạn phụ thuộc vào có sẵn trong trình nạp lớp ứng dụng của bạn, mà không cần phải đặt tên chúng một cách rõ ràng hoặc phân lớp chúng một cách riêng biệt. Điều này có lợi ích của việc đảm bảo rằng bất kỳ hệ thống blackbox nào bạn kiểm soát được (gửi đến jsp handler, vv) cũng sẽ có quyền truy cập vào các lớp đó (nếu chúng được bắt đầu với cùng một trình nạp lớp ứng dụng của triển khai). – Rhys

0

@Rage: This question trên stackoverflow được hỏi trước đó có thể cung cấp cho bạn một số thông tin về cách sắp xếp các lọ: có thể là bình của riêng bạn hoặc bên thứ ba.

0

Hãy thử điều này (tôi đã nắm lấy nó ở đâu đó trên Internet):

import java.io.File; 
import java.io.IOException; 
import java.lang.reflect.Method; 
import java.net.URL; 
import java.net.URLClassLoader; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 


public final class ClassPathHacker { 
    private static final Class<?>[] PARAMS = new Class<?>[] { URL.class }; 
    private static final Logger LOG_CPH = LoggerFactory.getLogger(ClassPathHacker.class); 

    private ClassPathHacker() {} 

    public static void addFile(final String pFileName) throws IOException { 
     final File myFile = new File(pFileName); 

     ClassPathHacker.addFile(myFile); 
    } 

    public static void addFile(final File pFile) throws IOException { 
     ClassPathHacker.addURL(pFile.toURI().toURL()); 
    } 

    public static void addURL(final URL pFileUrl) throws IOException { 

     /* variables definition */ 
     final URLClassLoader sysLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); 
     final Class<?> sysClass = URLClassLoader.class; 

     try { 
      final Method myMethod = sysClass.getDeclaredMethod("addURL", PARAMS); 

      myMethod.setAccessible(true); 
      myMethod.invoke(sysLoader, new Object[] { pFileUrl }); 
     } catch (final Exception exc) { 
      ClassPathHacker.LOG_CPH.error(exc.getLocalizedMessage(), exc); 

      throw new IOException(exc.getLocalizedMessage()); 
     } 
    } 
} 

Cùng với phương pháp này:

private static void hackClassPath(final File myData) { 
    if (myData.isDirectory()) { 

     /* block variables */ 
     final File[] myList = myData.listFiles(); 

     /* hacking classpath... */ 
     for (final File tmp : myList) { 
      try { 
       ClassPathHacker.addFile(tmp.getAbsolutePath()); 
       MainApplication.MAIN_LOG.trace("{} added to classpath", 
               tmp.getAbsolutePath()); 
      } catch (final IOException iOE) { 
       MainApplication.MAIN_LOG.error(iOE.getLocalizedMessage(), 
               iOE); 
      } 
     } 
    } 
} 

Và với cuộc gọi mẫu này:

MainApplication.hackClassPath(new File("test/data")); 
    MainApplication.hackClassPath(new File("data")); 

Một chút hacky, nhưng có lẽ nó hoạt động ... nó thời gian chạy thêm tất cả các tập tin JAr có sẵn trong dữ liệu hoặc kiểm tra/dữ liệu thư mục để chạy cl asspath.

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