|
SageTV Studio Discussion related to the SageTV Studio application produced by SageTV. Questions, issues, problems, suggestions, etc. relating to the Studio software application should be posted here. |
|
Thread Tools | Search this Thread | Display Modes |
#1
|
|||
|
|||
Stumped at java exception
My java code has been coming along well, but I recently tried something new and when I try to execute it in Sage, it gives an exception.
Basically I'm trying to abstract out the sage.SageTV.api() calls to another java class, kind of like neilm did, but more specific than his generic SageApi. Basically, the sage api class is like this: public class SageCQCApi { public static void Play() throws InvocationTargetException} And the java that calls it is: try { SageCQCApi.Play();} catch (InvocationTargetException e) { System.out.println("SageCQCServer (ERROR): " + e.toString());} However, when this code runs, I get an exception at the SageCQCApi.Play() call....the system.out message below it never executes. The annoying thing is that the catch also never executes...so it must not be an invocationTargetexception. At this point, the class definition of SageCQCApi is in it's own .java file, and the executeable code that calls it is in another .java file. They compile together fine, but upon executing I get "Exception in thread startup-SageCQCServer...etc", with no specifics. I think perhaps they aren't linking correctly? I've tried setting up packages and all that and had mixed success...but if they're both just .java files in the same directory, won't they compile and "link"? thanks for any help. |
#2
|
|||
|
|||
So long as both classes are on the JVM's classpath, it should find and load them OK.
Why not stick in a second catch block? catch (Throwable t) { System.out.println("Unexpected error: " + t.toString()); } Might give you a better idea of the underlying problem at least. |
#3
|
||||
|
||||
Several points:
a) your message implies that are not executing it from inside SageTV, but from a stand-alone EXE b) Play() is a UI-linked studio function, so you need to supply a UIcontext and call Sage.sage.apiUI()... Catching throwables is always a good idea What is probably happening is that there is a NPE somewhere in the Sage.sage.api() because you are not running in a SageTV process which is converted to an UnexpectedException because it is not defined in the Throw block And note that InvocationTargetExceptions are not very useful in themselves, but they have a Cause sub-exception (e.getCause()) which may contain the actual cause... (eg supplying a null argument)
__________________
Check out my enhancements for Sage in the Sage Customisations and Sageplugins Wiki Last edited by nielm; 07-25-2006 at 04:56 AM. |
#4
|
||||
|
||||
Always debug with the console window enabled, so you can see the stack dumps Sage prints out on errors.
To enable the console window, define the following value under HKEY_LOCAL_MACHINE\SOFTWARE\Frey Technologies\Common: consolewin REG_DWORD 1
__________________
-- Greg |
#5
|
|||
|
|||
Wow, thanks for all the help, guys. Sorry I didn't include a lot of detail as to how or what I'm doing.
First off, I definitely have the console window open. That's where the exception is stated. I also track progress of the algorithm with different system.out messages. Neilm, thanks a lot of your help because your code has been the guide so far. I should have made clear...up until I tried to move all the api calls into their own class, it was all working just great! I was able to send a "Pause" command over TCP from another program, and my .java running in sage received the command and would actually pause the playback in Sage. 1) I'm executing this code via Sage, via that load-at-startup thing in the sage.properties file....just like GetStatus does. I verify via system.out messages in the console that the server binds a socket, and accepts the client connection when it comes. 2) I saw the UI context based api calls, and couldn't figure out when and where I needed to use them. The API document in the forums didn't list the "Play" api call as being a ui or context based call, so I didn't include it there. I also want to say that up until I made this change, this was the code I had for sending the play command: if (inputLine.equals("Play")) { System.out.println("SageCQCServer: PLAY command received");} That was the code that I had in place of the SageCQCApi.Play() call above, and it worked just great! So, here's basically the problem: I was able to Play, and Pause video playback using my .java code running in Sage and receiving data over TCP from a connected client. However, when I tried to remove all of the api calls into a separate class (for organizational purposes) and tried to do the same tasks, I started getting the exception. It seemed like even though the code would compile, when it got to the SageCQCApi.Play() call, it didn't know what it was. Putting another throwable wrapper around the code is a great idea, I didn't know how to do that, so I'll give it a try and see if it sheds a little more light on the subject, thanks! Again, thanks for all the help so far. I can post the entirety of the pre-broken and post-broken code if that will help...the files aren't TOO big. Or I could upload them somewhere. |
#6
|
||||
|
||||
Quote:
__________________
-- Greg |
#7
|
|||
|
|||
Ok, that's a good rule I spose...no harm in specifying it. Of course, that's some of the reason I'm trying to move all of the api calls into a separate class, so I can implement things like UI context calls without cluttering up the main logic.
Thanks for the clarification on the ui context calls, though I'm still confident that this isn't the reason for the exception because it was working fine with the code above. |
#8
|
|||
|
|||
Ok, so I'm returning my code to working status, which means all the sage api calls are directly in the main code, not in a separate class. I'll then select one statement and attempt to move that to an external class. (I can't try this out for another 3 hours, when I get home from work).
I'm going to change the code from: String returnVal = sage.SageTV.api("GetProperty", new Object[]{"sageCQCserver/port", null}); to: String returnVal = SageCQCApi.GetProperty("sageCQCserver/port"); And create the SageCQCApi class in the appropriate .java file: import java.lang.reflect.InvocationTargetException; import java.lang.String; public class SageCQCApi { public static Object GetProperty(String property) throws InvocationTargetException} That's my plan. Anyone see anything obviously wrong with this? I'll let you know what happens when I run it, but this isn't really any different that what was giving me the exception last night. |
#9
|
|||
|
|||
Quote:
Although not all methods really need it, I would think GetProperty() is one of those which does (well this is just a guess on my side, I don't know for sure): since different MVPs can call this method, the server would need to know from which property file to retrieve the value ... So if your code still doesnt work, try passing in a UI context ... Dirk |
#10
|
|||
|
|||
Well, it caused the exception right at the SageCQCApi call, and thanks to Mahoney, I was able to catch that exception and output it:
Unexpected error: java.lang.NoClassDefFoundError: SageCQCApi So it was as I thought....I realize with java there really is no "linking" is there? In that case, why can't it find this class definition? The SageCQCApi.class file is in the same directory as the code above. I don't "import" the SageCQCApi because it's not a package, and from what I understand, it shouldn't need to be. Basically, the SageCQCServer class is the one that calls functions from the SageCQCApi class. I have both .java files in the same directory and I compile first the SageCQCApi.java file, then the SageCQCServer file. |
#11
|
||||
|
||||
Best way to make sure everything gets loaded is to package it all into a .jar file and drop that into your SageTV\JARs folder.
__________________
-- Greg |
#12
|
|||
|
|||
Making .jar files is a mystery to me....I'll have to google that unless there is a handy tutorial somewhere.
|
#13
|
|||
|
|||
Well, a little googling helped. I made a .jar file, put it in the JARs directory...and it APPEARS to be working. I still don't understand why it didn't before, but I'm content that it is now. Thanks for the help and suggestions...now to test the rest!
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
|
|