Link to home
Start Free TrialLog in
Avatar of mscprojhk
mscprojhk

asked on

How to time out calling a function from an application

inside my program, it will call a function of 3rd party java class, but sometimes it may hang and no error/exception thrown. then, my application doesn't work properly.

i want to know how to make the following thrown an exception after a period of time to my main program, some timeout exception? then, my application can continue processing.

try {          
              objLog.info("before convert");  
                jpegConverted = objConvertService.convert(_objAttachment.getData(),sExtension,"JPEG",((docconv.service.ImageProfile) (objObject)));
                objLog.info("after convert");
            } catch(IllegalFileTypeException _objIlegalfiletypeexception) {
                objLog.err(sContentName + ": Illegal File Type Exception returned by transcoder.",_objIlegalfiletypeexception);
                convertSuccess = false;
            } catch(ConvertException _objConvertexception) {
                objLog.err(sContentName + ": Convert Exception returned by transcoder.",_objConvertexception);
                convertSuccess = false;
            } catch(Exception _objException) {
                objLog.err(sContentName + ": Others Exception returned by transcoder.",_objException);
                convertSuccess = false;
            }
Avatar of Webstorm
Webstorm

Hi mscprojhk,

you can use thread :


    private <what_your_function_should_return> methodName( ... ) throws Exception // if any
    { ... }

    private Exception call_ex;
    provate <what_your_function_should_return> call_result;

    public <what_your_function_should_return> timeoutCall(int timeout, ... ) throws Exception // if any
    {
         Thread th=new Thread(){
             public void run()
             {
                  try{call_result=methodName( ... );
                  }catch(Exception ex){call_ex=ex;}
             }
             };
          call_ex=null;
          th.start();
          th.join(timeout);
          th.interrupt();
          if (call_ex!=null) throw call_ex;
          return call_result;
    }
>>         th.interrupt();
Or instead :

         if (th.isAlive())
         {
             th.interrupt();
             throw new Exception("Timeout");
         }
A bad behaving code might not consider thread interrupts (either it catches and ignores it or it does not check for it and doesn't call any API method that checks for it).
If that is your case then you may want to use th.stop() which is a deprecated method but is the strongest action you can to take to make
that logic stop. I don't think there is any fear about not having this method around in the next versions of Java (it is there in 6.0) but if
you decide to use it then maybe you want read about why it became depreacted  at http://java.sun.com/j2se/1.3/docs/guide/misc/threadPrimitiveDeprecation.html
Avatar of mscprojhk

ASKER

i got compilation error:
[javac] C:\opt\SVGT\Development\src\java\hk\com\smartone\svgtx\converter\Con
verter.java:104: local variable jpegConverted is accessed from within inner clas
s; needs to be declared final
[javac] jpegConverted = objConvertService.convert(_objAttachment.getData(),sExtension,"JPEG",((docconv.service.ImageProfile) (objObj
ect)));

as jpegConverted, _objAttachment, sExtension, objObject are outer class variables and some functions of outer class may need to get and set their values and can't assign those variables to final.

any methods to solve this?

try {  
    /*  original code       
    objLog.info("before convert");  
    jpegConverted = objConvertService.convert(_objAttachment.getData(),sExtension,"JPEG",((docconv.service.ImageProfile) (objObject)));
    objLog.info("after convert");
    */
    //
    Thread th = new Thread()
    {
       public void run()
       {
              objLog.info("before convert");  
              jpegConverted = objConvertService.convert(_objAttachment.getData(),sExtension,"JPEG",((docconv.service.ImageProfile) (objObject)));
              objLog.info("after convert");                 
       }
    };
    th.start();
    th.join(100 * 1000);
    if(th.isAlive())
    {
      th.interrupt();
      throw new Exception("Timeout");
    }    
    //                 
} catch(Exception _objException) {
      objLog.err(sContentName + ": Others Exception returned by transcoder.",_objException);
      convertSuccess = false;
}
ASKER CERTIFIED SOLUTION
Avatar of aozarov
aozarov

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
1. i declare those variables at global variables as several methods will set/get those variables
2. if i define them to final, they cannot be changed the variable.
3. i tried to declare them at private global variables, it works on windows JDK1.4.2._07, but throw java.lang.IllegalAccessError mentioning can't access global variables from inner class on red hat linux JDK1.4.2_07
4. what's the use of jpegConverted[0] ? can we clarify more?

thanks!


>> 4. what's the use of jpegConverted[0] ? can we clarify more?

What aozarov mean, is you can use an final array of object :
    final <objtype>[] jpegConvertedArray=new <objtype>[]{ jpegConverted }

then you can use it in your inner class (in the run() method) and set the value of the first element :
    jpegConvertedArray[0] = ...

final is needed to access it from inner class, which mean you'll not be able to modify the array reference, but modifying the reference to the 1st element is allowed.