GWT Autobeans / NoClassDefFoundError:ما الخطأ الذي افعله؟
-
28-10-2019 - |
سؤال
أنا أحاول أن تسلسل أ بوجو ل JSON في جي دبليو تي استخدام الأوتوبين, ، وأستمر في تلقي أ NoClassDefFoundError
و ClassNotFoundException
, كلاهما يبحث عن org.json.JSONObject
.هذا في سياق الترميز أ مكان.
لقد قمت بإنشاء اختبار JUnit لعزل المشكلة.الاختبار هو:
@Test public void testGetToken() {
SearchCriterion searchCriterion = new JavaSearchCriterion("a", "b", ImmutableList.of("c"));
ResourcesPlace place = new ResourcesPlace(ImmutableList.of(searchCriterion));
String token = new Tokenizer().getToken(place);
assertNotNull(token);
}
وتتبع المكدس الخاص بي هو
java.lang.NoClassDefFoundError: org/json/JSONObject
at com.google.web.bindery.autobean.shared.impl.StringQuoter.quote(StringQuoter.java:69)
at com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl$PropertyGetter.encodeProperty(AutoBeanCodexImpl.java:411)
at com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl$PropertyGetter.visitValueProperty(AutoBeanCodexImpl.java:397)
at com.google.web.bindery.autobean.vm.impl.ProxyAutoBean.traverseProperties(ProxyAutoBean.java:260)
at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.traverse(AbstractAutoBean.java:166)
at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.accept(AbstractAutoBean.java:101)
at com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl.doEncode(AutoBeanCodexImpl.java:558)
at com.google.web.bindery.autobean.shared.AutoBeanCodex.encode(AutoBeanCodex.java:83)
at com.redacted.client.place.ResourcesPlace$Tokenizer.getToken(ResourcesPlace.java:62)
at com.redacted.client.place.ResourcesPlaceTokenizerTest.testGetToken(ResourcesPlaceTokenizerTest.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassNotFoundException: org.json.JSONObject
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
... 32 more
وإليك الجزء ذو الصلة من Tokenizer:
private MyFactory factory = AutoBeanFactorySource.create(MyFactory.class);
interface MyFactory extends AutoBeanFactory {
// Factory method for a simple AutoBean
AutoBean<SearchCriterion> person();
// Factory method for a non-simple type or to wrap an existing instance
AutoBean<SearchCriterion> person(SearchCriterion toWrap);
}
@Override
public String getToken(ResourcesPlace place) {
AutoBean<SearchCriterion> placeBean = factory.create(SearchCriterion.class, place.getSearchCriteria().get(0));
return AutoBeanCodex.encode(placeBean).getPayload();
}
لقد قمت بإضافة Autobeans المضمن في ملف .gwt.xml الخاص بي، ولكن يبدو أنني لا أزال أفتقد شيئًا ما.
المحلول
كيف يتم إطلاق عداء الاختبار؟تلك الفئات تنشأ من gwt/tools/redist/json/r2_20080312/json-1.5.jar
في GWT repo ويجب تعبئته في ملف gwt-servlet-deps.jar
.حاول إضافة هذا الجرة إلى مسار الفصل الخاص بتكوين التشغيل التجريبي الخاص بك لمعرفة ما إذا كان ذلك سيؤدي إلى مسحه.
نصائح أخرى
لو كنت مكانك، فسأحاول كتابة اختباراتي خارج حالة اختبار GWT قدر الإمكان.يستغرق إطلاقه قدرًا هائلاً من الوقت، وفي أفضل الأحوال يجب استخدامه لاختبارات التكامل وليس اختبارات الوحدة (بالطبع يمكننا الدخول في نظرية الاختلافات ولكني أستطرد).
إذا كنت تريد استخدام AutoBeans في اختباراتك، فالأمر في الواقع سهل للغاية.بمجرد حصولك على واجهات Proxy وFactory، يمكنك استخدامها
BeanFactory factory = AutoBeanFactorySource.create(BeanFactory.class);
model = factory.createMyBean().as();
إليك برنامج تعليمي سريع يمكنك نسخ الكود منه باستخدام GWT Autobeans في اختبارات JUnit.