Using external-library jars?

Using external-library jars?

Postby Cale Vinson » Mon May 10, 2010 11:40 am

I'm attempting to make use of the "Smack" (http://www.igniterealtime.org/projects/smack/) library inside the Iam framework.

Running the bot from inside Eclipse, its easy - all I need do is add the Smack jar files via: Properties -> Java Build Path -> Add jars. Not only does this remove errors, but the bot actually seems to be making contact with the appropriate jabber address.

But if I try to run at the command line, after doing a right-click -> Create JAR on "createJar.jardesc", the bot runs, but with none of the Smack functionality. I'm doubtless missing something obvious (Iams are my first experimentation with Java) - I presume I need to modify the "createJar.desc" file somehow to include the Smack jars?

- Cale
Cale Vinson
 
Posts: 25
Joined: Sun Mar 21, 2010 5:21 am

Re: Using external-library jars?

Postby admin » Mon May 10, 2010 9:03 pm

I presume I need to modify the "createJar.desc" file somehow to include the Smack jars?


Yes, the Smack jar would have to be included somehow. There's a variety of ways you can do that. You can make sure it's included in the JAR-file created by the jardesc script. Use right-click and Open -> Open with -> JAR Export Wizard and make sure the Smack JAR file has a check-box ticked.

Or you can add the JAR to the class-path when running your Iam. So it would look something like "java -cp smack.jar -jar IamFramework.jar".

Hope that helps.

Mark Boon
admin
Site Admin
 
Posts: 69
Joined: Thu Feb 18, 2010 9:54 pm

Re: Using external-library jars?

Postby Cale Vinson » Thu May 13, 2010 3:12 pm

admin wrote:
Yes, the Smack jar would have to be included somehow. There's a variety of ways you can do that. You can make sure it's included in the JAR-file created by the jardesc script. Use right-click and Open -> Open with -> JAR Export Wizard and make sure the Smack JAR file has a check-box ticked.

Or you can add the JAR to the class-path when running your Iam. So it would look something like "java -cp smack.jar -jar IamFramework.jar".

Hope that helps.

Mark Boon


Many thanks for your reply Mark, but I'm doubtless still missing something (and probably something obvious).

I tried both your suggestions above with no luck.

There were some oddities in using the jardesc approach. I couldn't get the jardesc wizard to accept the smack.jar, until I (temporarily) removed it from the build path. Changing options for the jardesc file didn't seem to be properly captured - for example, I could run the wizard, *not* chose the smack.jar, delete the MyIam.jar file for safety, recreate it using right-click on jardesc, and the new MyIam.jar file would *still* contain smack.jar.

Here's what I get, trying the second approach:

Code: Select all
java -cp smack.jar;smackx.jar -jar IamFramework.jar
0    [main] INFO  com.avatar_reality.blue_mars.iam.IamBeanHelper.getIamBeans(Iam
BeanHelper.java:63) - Found 1 xml files
57   [main] INFO  org.springframework.beans.factory.xml.XmlBeanDefinitionReader.
loadBeanDefinitions(XmlBeanDefinitionReader.java:323) - Loading XML bean definitions
 from file [?????????\JabberBridge\MyIam.xml]
148  [main] ERROR com.avatar_reality.blue_mars.iam.IamBeanHelper.readXMLFile(Iam
BeanHelper.java:140) - Unexpected exception org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'testIam' defined in file [????????\JabberBridge\MyIam.xml]:
Cannot resolve reference to bean 'MyIamBehavior' while setting bean property 'behaviorList' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MyIamBehavior' defined
in file [???????\JabberBridge\MyIam.xml]: Instantiation of bean failed; nested exception is
 java.lang.NoClassDefFoundError: org/jivesoftware/smack/XMPPException
No Iams logged in.


- Cale
Cale Vinson
 
Posts: 25
Joined: Sun Mar 21, 2010 5:21 am

Re: Using external-library jars?

Postby admin » Thu May 13, 2010 6:41 pm

The error shown seems to hint at an error in your MyIam.xml

Can you send it to me, I'll take a look at it.

Mark
admin
Site Admin
 
Posts: 69
Joined: Thu Feb 18, 2010 9:54 pm

Re: Using external-library jars?

Postby admin » Thu May 13, 2010 6:57 pm

One coffee later...

Yes, it seems it didn't find a class from the smack.jar. It's difficult for me to pin-point the reason from a distance. Is the smack.jar in the same directory as the IamFramework.jar? When you unzip it (rename it to smack.zip and use 7zip to extract) can you find "org/jivesoftware/smack/XMPPException"?

Make sure you don't have two references to smack.jar, one in MyIam.jar and one in your path. And lastly, does the XML refer properly to MyIam.jar? Because that's something that would not be detected when running from Eclipse.

It's not as bad as DLL hell, but figuring out how to include all the libraries properly can be one of the frustrating parts of Java programming.

Mark Boon
admin
Site Admin
 
Posts: 69
Joined: Thu Feb 18, 2010 9:54 pm

Re: Using external-library jars?

Postby Cale Vinson » Sat May 15, 2010 6:51 am

Mark, first and foremost - thank you for your patience in dealing with this, given that we're largely talking about Java in general rather than the IamFramework in particular. I think I now have a fix, albeit an ugly one, so if you want to flag this thread as "done" that's fine by me. :) I'm documenting what I've done here on the (very) odd chance that it might be useful for reference later.

===================================

Partial Fix One.

A little knowledge is a dangerous thing :D , but as I understand it, if you use the "-jar" option on the java command, that invalidates the class-path that would otherwise be set by the -cp option. What I think you have to do is set class-paths via the jar Manifest file instead.

Using the createJar.jardesc to create the "MyIam.jar" file yields a jar file with a trivial Manifest file:

Code: Select all
Manifest-Version: 1.0


and I get the errors reported above.

If I manually edit the Manifest file to include smack on the classpath via:

Code: Select all
Manifest-Version: 1.0
Class-Path: smack.jar smackx.jar


I can then run "java -jar IamFramework.jar" and it *almost* works. By which I mean there are no errors, the bot starts talking to Jabber, but then stops for no apparent reason after its exchanged a few messages.

Total (but ugly) Fix Two.

As you pointed out, jar files are just zips. So, I created a "IamFrameworkSmack.jar" by taking a copy of "IamFramework.jar" and copying into it the relevant directories from the smack jars. I can then just run "java -jar IamFrameworkSmack.jar" and everything works perfectly (knock wood :) ). Of course, I'll have to repeat that process whenever you upgrade the framework, but it takes all of one minute to do, and after hours of Java-newbie-flailing-around I'm just relieved to have something that works.

- Cale
Cale Vinson
 
Posts: 25
Joined: Sun Mar 21, 2010 5:21 am

Re: Using external-library jars?

Postby admin » Mon May 17, 2010 8:24 pm

Cale,

A little knowledge is a dangerous thing , but as I understand it, if you use the "-jar" option on the java command, that invalidates the class-path that would otherwise be set by the -cp option. What I think you have to do is set class-paths via the jar Manifest file instead.


Sorry about that, I should have known that. Adding it to the manifest is not going to work because I dynamically load the MyIam.jar file and add it to the class-path internally. But I don't add any jars in it. I'm surprised it actually worked as far as you say it did.

With regards to Fix Two, don't ever do that again :)

Instead, it's better to use an Eclipse plug-in called FatJar to create the MyIam.jar (or whatever you decided to call it). The jardesc functionality was originally actually derived from the FatJar project, but the original offers some nice extra features. One of which is to automatically unzip JAR-files you're using and adding the contents to your JAR-file. That's less work and less error-prone. In Eclipse, go to Help -> Install New Software... and add the following update URL: http://kurucz-grafika.de/fatjar and install it.

Now, if you create a file that ends in .fatjar Eclipse has some extra menu items related to it when you right-click the file. Choose FatJar -> Build and check the "One-JAR" checkbox and click Next. Now you can verify that the JAR-files you need are actually included. You may also want to uncheck some junk that you don't need to have included, like some XML files. Note that it requires you to enter a main class name. For this you can use the TestMyIam class, but I think you can fill in whatever you like. As long as it's not empty, it's not used anyway.

It also has the added benefit over your method that it doesn't modify IamFramework.jar, which is going to haunt you some day. I used this to create the IamFramework.jar file, which contains quite a few libraries.

I'll add a page to the Wiki describing the use of FatJar, as I'm pretty sure almost every bot-developer is going to need it.

Do I understand you got your Iam to work now? That's great! Still, I advise you to use FatJar and go back and use the clean IamFramework as it was provided.

Good luck and let us know when we can try out your new Iam.

Mark
admin
Site Admin
 
Posts: 69
Joined: Thu Feb 18, 2010 9:54 pm

Re: Using external-library jars?

Postby Cale Vinson » Wed May 19, 2010 12:58 am

Here's where I'm currently at.

a) It needs a lot more than the 20 minute test I've done thus far, but, yes, it does seem to be currently working - I can run a Jabber client program ("Spark" in my case) and use it to send messages to and from the Iam.

b) Ultimate goal of this project is to enable communities that span both SL and BM to keep in touch, via in-world communication. Idea is to have both SL and BM bots picking up targeted local chat, and directing it to the "other" world. Ie., if I'm in BM and want my message to go to SL too, I'd type: "!SL My-message-goes-here" into the BM chat box.

c) The project fails if either link does. So, having a proof-of-concept model now running on the BM side, I'm currently looking at the SL side. Once I get that running, I'll then need to do a pass through both sets of code and fix up all the bits I missed initially (error-checking on failed login when servers are down, etc).

d) I am, of course, suitably chastened by your admonishment regarding Fix Two. :) My plan is to look at the "FatJar" approach as part of the clean-up process in (c) (and I'll report back on how its goes). But, if it'd be useful for you to have feedback quicker, I can re-order these tasks.

- Cale
Cale Vinson
 
Posts: 25
Joined: Sun Mar 21, 2010 5:21 am

Re: Using external-library jars?

Postby admin » Wed May 19, 2010 1:17 am

d) I am, of course, suitably chastened by your admonishment regarding Fix Two. My plan is to look at the "FatJar" approach as part of the clean-up process in (c) (and I'll report back on how its goes). But, if it'd be useful for you to have feedback quicker, I can re-order these tasks.


I mailed you an alternative approach at add JARs. If it's not too inconvenient I'd like to confirm that it works for you, then I can update the Wiki to describe what are the recommended ways to refer to external libraries.

Ultimate goal of this project is to enable communities that span both SL and BM to keep in touch, via in-world communication.


Modern version of the Walkie-Talkie :lol:

Mark Boon
admin
Site Admin
 
Posts: 69
Joined: Thu Feb 18, 2010 9:54 pm

Re: Using external-library jars?

Postby Cale Vinson » Wed May 19, 2010 2:50 pm

admin wrote:I mailed you an alternative approach at add JARs. If it's not too inconvenient I'd like to confirm that it works for you, then I can update the Wiki to describe what are the recommended ways to refer to external libraries.


OK, mixed success with your suggestions thus far .....

1) The method you emailed me with (using beans) worked perfectly. I like it. :)

2) The "fatjar" method I couldn't get to work.

Here's what a "java -jar IamFramework" produces:

Code: Select all
java  -jar IamFramework.jar
0    [main] INFO  com.avatar_reality.blue_mars.iam.IamBeanHelper.getIamBeans(Iam
BeanHelper.java:63) - Found 1 xml files
62   [main] INFO  org.springframework.beans.factory.xml.XmlBeanDefinitionReader.
loadBeanDefinitions(XmlBeanDefinitionReader.java:323) - Loading XML bean definit
ions from file [?????????\MyIam.xml]
156  [main] ERROR com.avatar_reality.blue_mars.iam.IamBeanHelper.readXMLFile(Iam
BeanHelper.java:140) - Unexpected exception org.springframework.beans.factory.Be
anCreationException: Error creating bean with name 'testIam' defined in file [???????\MyIam.x
ml]: Cannot resolve reference to bean 'MyIamBehavior' while setting bean propert
y 'behaviorList' with key [0]; nested exception is org.springframework.beans.fac
tory.CannotLoadBeanClassException: Cannot find class [JabberBehaviour] for bean
with name 'MyIamBehavior' defined in file [????????\MyIam.xml]; nested exception is java.lang.
ClassNotFoundException: JabberBehaviour
No Iams logged in.


Now, the "ClassNotFoundException: JabberBehaviour" had me worried that I had completely mucked up the fatjar creation. So, I unzipped "MyIam.jar" to have a look at what was in there. Here's the directory structure:

Code: Select all
├──com
│  └──simontuffs
│     └──onejar
├──lib
├──main
└──META-INF


The "main" directory has a single file "main.jar", and that jar file contains the three classes I expect: "JabberBehaviour.class", "JabberSmackAPI.class", and "TestMyIam.class". The root directory of the above tree has a single class file, "OneJar.class". The "lib" directory has the two external jar files, "smack.jar" and smackx.jar" - I may have misunderstood what you were trying to tell me, but I thought you indicated that these should end up unzipped, but they weren't.

I probably have the fatjar incorrectly set-up - not wildly so (given that all the necessary classes and jars do seem to be in there), but enough to break things. :)

- Cale

ps. If this was about me and me alone (which it isn't), I'd use the bean method and forget about "fatjar". But I also think GUIs are over-rated in general. :twisted:
Cale Vinson
 
Posts: 25
Joined: Sun Mar 21, 2010 5:21 am

Next

Return to General Discussions

Who is online

Users browsing this forum: No registered users and 1 guest

cron