2010-07-07 3 views
3

Я пытаюсь использовать Reflection на стороне сервера только из приложения GWT. У меня есть базовый пример, который работает в примере, отличном от GWT, который можно увидеть ниже.GWT Отражение на стороне сервера

package com.xyz.reflection; 

import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 

public class EntryPoint { 

/** 
* @param args 
*/ 
public static void main(String[] args) { 

    ClassLoader dynClassLoader = ClassLoader.getSystemClassLoader(); 

    Class<?> dynClass = null; 
    try { 
     dynClass = dynClassLoader.loadClass("com.xyz.reflection.RunMe"); 
    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } 

    Object dynInstance = null; 
    try { 
     dynInstance = dynClass.newInstance(); 
    } catch (InstantiationException e) { 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } 

    Method dynMethod = null; 
    try { 
     try { 
      dynMethod = dynInstance.getClass().getMethod("returnSid", 
        new Class[] { PassMe.class }); 

     } catch (SecurityException e) { 
      e.printStackTrace(); 
     } catch (NoSuchMethodException e) { 
      e.printStackTrace(); 
     } 

     String returnValue = (String) dynMethod.invoke(dynInstance, 
       new Object[] { new PassMe() }); 

     System.out.println("Return Value: " + returnValue.toString()); 

    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (IllegalArgumentException e) { 
     e.printStackTrace(); 
    } catch (InvocationTargetException e) { 
     e.printStackTrace(); 
    } 
} 

}

используя метко назвал:

package com.xyz.reflection; 

public class PassMe { 

private String sid = "DEFAULT_SID"; 

public PassMe() { 
    this.sid = "INITIATED_SID"; 
} 

public String getSid() { 
    return sid; 
} 

public void setSid(String sid) { 
    this.sid = sid; 
} 

}

и:

package com.xyz.reflection; 


public class RunMe { 

    public String returnSid(PassMe s) { 
     return s.getSid(); 
    } 
} 

Это прекрасно работает. При попытке запуска это с серверной стороны класса GWT он не работает, а вместо этого возвращает

java.lang.NoSuchMethodException: com.xyz.reflection.RunMe.returnSid(com.xyz.reflection.PassMe) 

Если изменить параметр в строку (вместо класса в «PassMe») она отлично работает. Почему мне не нравится проходить мой класс «PassMe»? Я думал, что это может быть проблема с сериализацией, несмотря на то, что это 100% -ный код сервера, но мне тоже не повезло.

Заранее благодарим за любую помощь, которую любой может дать мне с этим.

+0

Что вы используете для запуска сервера GWT (режим размещения в GWT? Автономный или встроенный контейнер WAR (например, Jetty)? – Syntax

ответ

1

В дополнение к решению Финрод, вы также можете изменить свой загрузчик классов, чтобы что-то вроде:

ClassLoader dynClassLoader = PassMe.class.getClassLoader(); 

И вы можете использовать поиск PassMe.class стиль снова. Класс, используемый для поиска загрузчика, по-видимому, не имеет значения. Просто не системный загрузчик.

Странные вещи. Я бы не сомневался, что GWT делает что-то странное с загрузчиком классов.

Редактировать: Да. GWT устанавливает загрузчик системного класса в com.google.appengine.tools.development.IsolatedAppClassLoader в режиме dev.

+0

Отлично! Все, что мне пришлось изменить, это линия, которую вы выделили, и она работает как сон. Благодаря себе и финишу, который получил мяч. +1 для вас обоих: o) Извините за отложенный ответ, меня не было в отпуске. Для дальнейшего чтения на дорогах классов я нашел эту старую, но содержательную статью: http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html?page=1 – specialtrevor

0

Это в значительной степени выстрел в темноте, но это помогает, если заменить dynMethod = dynInstance.getClass().getMethod("returnSid", new Class[] { PassMe.class });

с

dynMethod = dynInstance.getClass().getMethod("returnSid", PassMe.class); ?

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

+0

Приятная попытка, но без сигары. К сожалению, это, похоже, не имеет значения, но очень спасибо за щадящее время, пытаясь помочь. – specialtrevor

0

Вы поместили свой файл отражения в пакет на стороне сервера? Например:
org.myproject.client - ваш GWT пакет клиента (поместить сюда ваши Java-файлы, которые способны быть выполнены в Java Script NO REFLECTION)
org.myproject.server - поместить здесь любой Java файлы, включая отражение
org.myproject.shared - поставить здесь классы Java, которые способны быть скомпилирован в Java Script

+0

Я попытался с кодом отражения, находящимся в 'org.myproject.server' и в 'org.external.reflection' (включая внешний проект/пакет в пути сборки) и не имеет никакого значения. Для подтверждения, ни один из файлов * .gwt.xml для исходного пути клиента не сохраняется. Это остается следующим: Спасибо за ваше время. – specialtrevor

1

Я думаю, что это может быть связано с классом нагрузки - но это только догадка, как я не могу экспериментировать с ним в контексте, подобном вашему.

Вот некоторые предложения попробовать:

Вы используете:

ClassLoader dynClassLoader = ClassLoader.getSystemClassLoader(); 

dynClass = dynClassLoader.loadClass("com.xyz.reflection.RunMe"); 

Для загрузки Runme класса.

Однако, чтобы загрузить класс PassMe вы используете:

PassMe.class 

Попробуйте загрузить PassMe класса через dynClassLoader и использовать этот экземпляр в getMethod() вместо PassMe.class.

Интересно, вам нужно использовать dynClassLoader?

+0

Мне было любопытно, поэтому я попробовал. Если вы используете sam e loader для создания экземпляра PassMe, он отлично работает. Вероятно, есть много чего с секретным соусом RPW GTP. –

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