SageTV Community  

Go Back   SageTV Community > SageTV Development and Customizations > SageTV Studio
Forum Rules FAQs Community Downloads Today's Posts Search

Notices

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.

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 07-25-2006, 01:37 AM
beelzerob beelzerob is offline
Sage Advanced User
 
Join Date: May 2006
Posts: 163
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
{
sage.SageTV.api("Play", null);
}
}


And the java that calls it is:

try
{
SageCQCApi.Play();
System.out.println("I tried to 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.
Reply With Quote
  #2  
Old 07-25-2006, 02:25 AM
Mahoney Mahoney is offline
Sage Aficionado
 
Join Date: May 2005
Posts: 483
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.
Reply With Quote
  #3  
Old 07-25-2006, 04:51 AM
nielm's Avatar
nielm nielm is offline
SageTVaholic
 
Join Date: Oct 2003
Location: Belgium
Posts: 4,496
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.
Reply With Quote
  #4  
Old 07-25-2006, 09:20 AM
GKusnick's Avatar
GKusnick GKusnick is offline
SageTVaholic
 
Join Date: Dec 2005
Posts: 5,083
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
Reply With Quote
  #5  
Old 07-25-2006, 10:29 AM
beelzerob beelzerob is offline
Sage Advanced User
 
Join Date: May 2006
Posts: 163
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");
sage.SageTV.api("Play", null);
}


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.
Reply With Quote
  #6  
Old 07-25-2006, 10:51 AM
GKusnick's Avatar
GKusnick GKusnick is offline
SageTVaholic
 
Join Date: Dec 2005
Posts: 5,083
Quote:
Originally Posted by beelzerob
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.
If you have three MVPs or Placeshifter clients running off the same server, which one should start playing when you call Play? That's what the UI context is for. My rule is to use the UI context for everything except global configuration properties that apply to all clients.
__________________
-- Greg
Reply With Quote
  #7  
Old 07-25-2006, 11:04 AM
beelzerob beelzerob is offline
Sage Advanced User
 
Join Date: May 2006
Posts: 163
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.
Reply With Quote
  #8  
Old 07-25-2006, 05:52 PM
beelzerob beelzerob is offline
Sage Advanced User
 
Join Date: May 2006
Posts: 163
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
{
return sage.SageTV.api("GetProperty", new Object[]{property, null});
}
}


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.
Reply With Quote
  #9  
Old 07-25-2006, 07:48 PM
dflachbart dflachbart is offline
SageTVaholic
 
Join Date: Jan 2006
Location: Brookfield, CT
Posts: 2,743
Quote:
Originally Posted by beelzerob
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
{

return sage.SageTV.api("GetProperty", new Object[]{property, null});

}

}

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.
I have almost the same exact code in my utility library, and it works just fine. Only difference: I always use SageTV.apiUI(...) in my wrapper methods ...

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
Reply With Quote
  #10  
Old 07-25-2006, 09:49 PM
beelzerob beelzerob is offline
Sage Advanced User
 
Join Date: May 2006
Posts: 163
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.
Reply With Quote
  #11  
Old 07-25-2006, 10:37 PM
GKusnick's Avatar
GKusnick GKusnick is offline
SageTVaholic
 
Join Date: Dec 2005
Posts: 5,083
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
Reply With Quote
  #12  
Old 07-25-2006, 11:10 PM
beelzerob beelzerob is offline
Sage Advanced User
 
Join Date: May 2006
Posts: 163
Making .jar files is a mystery to me....I'll have to google that unless there is a handy tutorial somewhere.
Reply With Quote
  #13  
Old 07-25-2006, 11:46 PM
beelzerob beelzerob is offline
Sage Advanced User
 
Join Date: May 2006
Posts: 163
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!
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -6. The time now is 04:19 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2023, vBulletin Solutions Inc.
Copyright 2003-2005 SageTV, LLC. All rights reserved.