2009-10-02 6 views
2

Я написал простой проект с использованием java rmi и экспортировал его в исполняемый файл jar. Когда я пытаюсь запустить его, иногда я получаю исключения и иногда это работает. Когда я указываю -Djava.rmi.server.codebase = file: serverClasses /, кажется, что он не создал файл jar правильно. Вот StackTrace:Класс rmi не найден Исключение

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: com.ServerBootstrap.IServer 
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:413) 
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267) 
    at sun.rmi.transport.Transport$1.run(Transport.java:177) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173) 
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
    at java.lang.Thread.run(Thread.java:636) 
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273) 
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251) 
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377) 
    at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source) 
    at java.rmi.Naming.rebind(Naming.java:177) 
    at com.v3q6.eece411.A2.ServerBootstrap.ChatRoomServer.main(ChatRoomServer.java:37) 
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: com.ServerBootstrap.IServer 
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source) 
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:403) 
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267) 
    at sun.rmi.transport.Transport$1.run(Transport.java:177) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173) 
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
    at java.lang.Thread.run(Thread.java:636) 
Caused by: java.lang.ClassNotFoundException: com.ServerBootstrap.IServer 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:217) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:323) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:268) 
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:264) 
    at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:728) 
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:672) 
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:609) 
    at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646) 
    at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311) 
    at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:255) 
    at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1548) 
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1510) 
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749) 
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346) 
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368) 
    ... 12 more 

Кажется, программа не признает кодовую. В моем случае все файлы являются локальными. Кто-нибудь знает, в чем проблема? спасибо

ответ

3

Попробуйте явно указать имя файла JAR, содержащего класс com.ServerBootstrap.IServer, в вашей кодовой базе данных, например.

-Djava.rmi.server.codebase=file:serverClasses/myjarfile.jar 

«Dynamic code downloading using JavaTM RMI (Using the java.rmi.server.codebase Property)» документ содержит более подробную информацию об использовании кода, и варианты его спецификации.

+0

он работает! Можно ли установить его где-то в другом месте, чтобы мне не приходилось добавлять это каждый раз. –

+0

@CKeven: вы можете сделать то же самое, используя 'System.getProperties(). SetProperty (name, value)' ... при условии, что вы делаете это достаточно рано. –

+0

Я не знаю, как это сделать. Не могли бы вы сказать мне прямо? thanks –

0

Это не полная stacktrace, и я думаю, что вы, возможно, оставили часть, которая показывает основную причину вашей проблемы.

Если я правильно помню, ClassNotFoundException иногда может возникать из-за исключения, возникшего во время статической инициализации загружаемого класса или определенного класса, от которого он зависит. Если это произойдет, оно будет отображаться как вложенное исключение в первом стеке для проблемы на следующем уровне вложенности. Я помню (возможно, неправильно), что если ваше приложение повторяет попытку загрузки класса, исключение инициализации не входит в итоговую стеквую таблицу.

РЕДАКТИРОВАТЬ: Полная стежка говорит, что моя теория неверна.

+0

Я просто положил их всех. Thx –

0

С относительным путем, указанным для java.rmi.server.codebase, убедитесь, что вы находитесь в правильном каталоге (родительский каталог «serverClasses») при запуске клиента. Если это трудно обеспечить, абсолютный путь для кодовой базы может быть более надежным.

Также помните, что при запуске с опцией -jar опция -classpath полностью игнорируется. Я не думаю, что здесь проблема. RMIClassLoader все равно должен работать, используя настройку базы кода сервера. Но если вы полагаетесь на то, что клиент имеет доступ к дополнительным классам, указанным в пути к классам, это не сработает. Вам нужно будет использовать атрибут Class-path в манифесте основного JAR-файла.

+0

Странно, что программа даже не распознает класс в файле jar. Вы знаете, почему? –

Смежные вопросы