# Client als Jar und die vielen Abhängigkeiten



## Weisswurst (21. Sep 2010)

Hi!

Ich bin gerade dabei meine EJB Kenntnisse wieder auf zu frischen.
Ich habe in Eclipse ein EJB Projekt, das ich auch schön auf meinem Jboss deployen kann.

```
BookTestBean/remote - EJB3.x Default Remote Business Interface
	BookTestBean/remote-de.helloTest.beaninterfaces.bookTestBeanRemote - EJB3.x Remote Business Interface
	BookTestBean/local - EJB3.x Default Local Business Interface
	BookTestBean/local-de.helloTest.beaninterfaces.bookTestBeanLocal - EJB3.x Local Business Interface
```
Ich habe des weitern ein Clientprojekt, das direkt mit dem EJB Projekt als "Required Project" verbunden ist.
Der Client funktioniert auch. Ich kann meine Bean über JNDI anrufen, bekomme gesagt wieviele Bücher in der Datenbank liegen, kann mir diese sogar auflisten lassen und kann sogar neue Bücher anlegen.

So, nun zum eigentlichen Problem.
Mein Client ist ein Apache pivot Client und sollte auch als Applet laufen können. Dazu muss ich den Client erstmal in ein JAR File packen. Und da fangen die Probleme an. Ich habe die BeanInterfaces aus dem EJB Projekt in ein Jar File gepackt und wollte das in den Classpath des Clients hängen. Innerhalb von Eclipse funktioniert das sogar.

Aber wenn ich den Client über Terminal als "java -jar ..." aufrufe dann funktioniert der Client nicht.
Momentan sieht mein Manifestfile so aus:


```
Manifest-Version: 1.0
Main-Class: de.test.HelloTestClient
Class-Path: lib/pivot-core-1.5.1.jar lib/pivot-wtk-1.5.1.jar lib/pivot-wtk-terra-1.5.1.jar lib/jnp-client.jar lib/jboss-logging.jar lib/helloTestBeanIf.jar lib/hibernate-jpa-2.0-api.jar
```

Zwischenzeitlich habe ich sogar alle Beanklassen aus dem EJB Projekt einfach in das Client Projekt kopiert.
Dennoch bekomme ich folgende Exception:


```
java.lang.ClassCastException: javax.naming.Reference cannot be cast to de.helloTest.beaninterfaces.bookTestBeanRemote
	at de.test.HelloTestClient.startup(HelloTestClient.java:81)
	at org.apache.pivot.wtk.DesktopApplicationContext$HostFrame.processWindowEvent(DesktopApplicationContext.java:95)
	at java.awt.Window.processEvent(Window.java:1823)
	at java.awt.Component.dispatchEventImpl(Component.java:4630)
	at java.awt.Container.dispatchEventImpl(Container.java:2099)
	at java.awt.Window.dispatchEventImpl(Window.java:2478)
	at java.awt.Component.dispatchEvent(Component.java:4460)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
```

Ich habe reichlich gegooglet und habe erfahren, dass diese Art von Fehler meist dann auftritt, wenn irgend eine Beanklasse nicht verfügbar ist. Das scheint auch zu passen, denn innerhalb von Eclipse ist der Cast kein Problem.
Der dazugehörige Quellcode (Exception in Zeile 27):


```
@Override
    public void startup(Display display, Map<String, String> properties) {
    	WTKXSerializer wtkxSerializer = new WTKXSerializer();
        try {
        	InputStream stream = new FileInputStream(dummy.class.getResource("hello.wtkx").getFile());
        	//InputStream stream = new FileInputStream("hello.wtkx");
        	window = (Window)wtkxSerializer.readObject(stream);
			wtkxSerializer.bind(this);
			addButton.getButtonPressListeners().add(this);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SerializationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		Properties jndiProperties = new Properties();
		jndiProperties.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
		jndiProperties.put("java.naming.factory.url.pkgs","=org.jboss.naming:org.jnp.interfaces");
		jndiProperties.put("java.naming.provider.url","localhost:1099");
		
		try {
			context = new InitialContext(jndiProperties);
			//Object obj = bookTestBeanRemote.class;
			bookTestBeanRemote beanRemote = (bookTestBeanRemote) context.lookup("BookTestBean/remote");
			//beanRemote.test();
			System.out.println("Bookcount: " + beanRemote.getAllBooks().size());
			
			ArrayList<Object> buchListenDaten = new ArrayList<Object>();
			for(Book b : beanRemote.getAllBooks()) {
				HashMap<String, String> row = new HashMap<String, String>();
					
					row.put("id", b.getId().toString());
					row.put("author", b.getAuthor());
					row.put("book", b.getTitle());
					buchListenDaten.add(row);
			}
			tableView.setTableData(buchListenDaten);
				
		} catch (NamingException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
       window.open(display);
    }
```

Da ich inzwischen alle Beanklassen aus dem EJB Projekt in das Clientprojekt kopiert habe muss die fehlende Klasse eine der Jboss jars sein. Ich habe, wie man am Manifest sehen kann schon einige aufgenommen. Aber irgendwas scheint immernoch zu fehlen. Aber ich kann doch nicht alle 164 Jbossclient jars in's Manifest hängen...
Irgendwo ist da der Wurm drin...

Danke euch!
Grüße


----------



## Marcinek (21. Sep 2010)

hast du die JBoss-all-client.jar passend zu deinem JBoss im Classpath?


Das lookup scheint dir etwas zu liefern, dass du falsch castest. (Ok das steht auch in deinem Posting ^^)

Hinweis: Packetnamen sind immer lowecase und Klassennammen beginnen mit einem Großbuchstaben.


----------



## Weisswurst (21. Sep 2010)

Ach jetzt seh ichs.
In der allclient.jar sind verweise auf die benötigten jar files.
So muss ich zwar praktisch alle beilegen, aber immerhin muss ich sie nicht in mein manifest schreiben.
thx!


----------

