2012-01-03 23 views
11

私はJBoss 7を使用しています(このバージョンでは依存関係の読み込みが変更されました)。 私のwar-applicationはサーバjarにアップロードされ、内部でクラスを使用する必要がありますが、ClassNotFoundExceptionを取得します。 私は動的依存関係をモジュールに動的に追加する方法を見つけることができません - MANIFEST.MFjboss-deployment-structure.xmlは静的な方法です。JBoss 7:動的にjarsをロードする方法

+1

JBoss 7では依存関係の読み込みが変更されました。以前のバージョンのJBossを使用してこれを行いましたか?以前のアプローチを説明できますか? – GargantuChet

+0

私は[このドキュメント](https://community.jboss.org/wiki/ModuleCompatibleClassloadingGuide)が助けになると推測します – higuaro

答えて

5

私は正しくそれを確認するために質問を言い直してください。

任意のjarファイルをサーバーにアップロードし、JVMで含まれているクラス/リソースを使用できるようにしたいですか? JVMを再起動したり、あなたの設定を編集したりせずに。

これが当てはまる場合は、(必要に応じて現在のクラスローダーを連鎖させて)クラスローダーにjarをロードし、そこからクラスをロードする必要があります。

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); 
} 

シモンズ:

あなたが例えばのような何かを行うことができ、サーバー上の物理的のjarファイルを保存すると仮定。これは粗雑なコードです、私はコンパイルしたりテストしたりしませんでした。それはする必要がありますが、それ以上何も見落として何かを見落としたり、タイプミスをしました;-)

Pps。カスタムjarファイルをアップロードすることができ、クラスを実行することで多数の(セキュリティ上の)リスクが発生します。

+0

私はこの回答が気に入っていますが、質問には答えられません。最終的にmanfiest/jboss-deployment-structure.xmlを介してjbossの依存関係を設定することの違いは、明示的に名前を付けたり、別々にクラスを読み込んだりすることなく、依存するすべてのクラスをアプリケーションクラスローダーで暗黙的に使用できるようにすることです。これは、あなたが処理するブラックボックスシステム(jspハンドラへのディスパッチなど)がそれらのクラスにアクセスできるようにするメリットがあります(デプロイメントの同じアプリケーションクラスローダーで起動されている場合)。 – Rhys

0

@Rage:This question on Javascriptを使用すると、Jarsを構成する方法を入力する前に、自分自身またはサードパーティ製のjarファイルを入力することができます。

0

この(私はインターネット上のどこかでそれをつかんできた)試してみてください。

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); 
      } 
     } 
    } 
} 

そして、このサンプル・コールと::

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

この方法で

一緒
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()); 
     } 
    } 
} 

を少しハッキリですが、おそらくそれは動作します...ランタイムは、データまたはテスト/データディレクトリで利用可能なすべてのJArファイルを実行中のclに追加します尻尾。

関連する問題