Forum Discussion

rgratis's avatar
rgratis
Frequent Contributor
14 years ago

Access Java properties files within open application (use ResourceBundle?)

I'm working with a packaged Java application (EXE).  The application is fairly open, so I have access to all the relevant Java classes and objects in TestComplete, but I'm having trouble figuring out if there's a way to access the resource bundles (and thus, localized strings) being used in the running application.  The properties files are in there somewhere...

Originally, I was trying to use java.util.ResourceBundle and
getBundle("path"), but it seems like I'm not loading the objects in the right context.



If anyone has worked through a similar situation, I would appreciate some help.



[To make it more "interesting", I'm scripting in VBScript, which adds another layer of abstraction.]
  • rgratis's avatar
    rgratis
    Frequent Contributor
    Okay, spent all morning wading through Java documentation and TestComplete's JavaRuntime/JavaClasses, and I finally got this working.  I solved it by getting a ClassLoader object from the top-level Java application object and using that as a parameter in ResourceBundle.getBundle.  I'm going to post my solution here in case anyone is trying to do this in the future.



    I used the top-level Java object in your application to get the ClassLoader object, like this:



    Set myLoader = Sys.Process("<Application>").SwingObject("<class>", "<Caption>").getClass().getClassLoader()



    I got the default Locale object from the application's JavaRuntime:



    Set myLocale = Sys.Process("Application").JavaRuntime.JavaClasses.java_util.Locale.getDefault()



    You could also pass a certain locale (constants inside java.util.Locale).



    I used these together with the ResourceBundle class to get a ResourceBundle object:



    Set myBundle = Sys.Process("Application").JavaRuntime.JavaClasses.java_util.ResourceBundle.getBundle("baseFileName", myLocale, myLoader)



    The base file name has to be the path to the properties file within the Java class structure, leaving off any locale suffix and the file extension.  For example, to get "myProps.properties" inside package "myPackage", the base filename would be "myPackage/myProps".



    Now that you have the resource bundle, you can get properties from it (see documentation for java.util.ResourceBundle).  Example:



    myBundle.getString("key.name")



    Below is the VBScript function I whipped up to get property strings for me. Comments/corrections welcome.





    Function getProperty(baseFile, key)

    ' Copyright 2011 Rachel Gratis, released for public use

    ' VBScript for TestComplete 8.6

    ' Returns a property string from the localized properties file

    ' useful for scripting UI text comparisons in internationalized Java apps

    ' baseFile is the class path to the properties file without locale suffix or file extension

    ' key is the property key inside the properties file

    ' Localization is determined by the default JavaRuntime locale in this script



      Dim myApp

      Dim myLoader

      Dim myLocale

      Dim myBundle

     

      ' Handle  exceptions

      On Error Resume Next

     

      ' Init Null

      getProperty = Null

     

      ' Convert to strings

      baseFile = aqConvert.VarToStr(baseFile)

      key = aqConvert.VarToStr(key)



      ' Check for empty strings

      If Not baseFile <> "" Or Not key <> "" Then

        Log.Error "Error obtaining language string.", "Base name for the properties file and the property key must be provided."

        Exit Function

      End If

     

      ' Make certain process exists

      If Not Sys.Process("<Application>").Exists Then

        Log.Error "Error obtaining language string.", "Could not find application system process."

        Exit Function

     

      ' Make certain app window exists

      ElseIf Not Sys.Process("<Application>").SwingObject("<class>", "<Caption>").Exists Then

        Log.Error "Error obtaining language string.", "Could not find application object."

        Exit Function

        

      End If 'process/window objects don't exist

     

      ' Get process reference

      Set myApp = Sys.Process("<Application>")



      ' Try to get ClassLoader from top-level application object

      Set myLoader = myApp.SwingObject("<class>", "<Caption>").getClass().getClassLoader()

     

      ' Check for SecurityException

      If Err.Number <> 0 Then



        Log.Error "Error obtaining language string.", "Failed to obtain Java ClassLoader object." & VbCrLf &  "Error " & Err.Number & ": " & Err.Source & VbCrLf & Err.Description

        Err.Clear

        

        Set myApp = Nothing

        Exit Function

        

      ' Check for Java null ClassLoader

      ElseIf myLoader Is Nothing Then

     

        Log.Error "Error obtaining language string.", "Failed to obtain Java ClassLoader object." & VbCrLf &  "Application returned a null ClassLoader."

        

        Set myApp = Nothing

        Exit Function

        

      End If 'could not get ClassLoader



      ' Get default locale

      ' If you wanted to specify a locale, you could also get a constant from Locale here

      Set myLocale = myApp.JavaRuntime.JavaClasses.java_util.Locale.getDefault()

     

      ' Try to get bundle

      Set myBundle = myApp.JavaRuntime.JavaClasses.java_util.ResourceBundle.getBundle(baseFile, myLocale, myLoader)

     

      'Check for exceptions

      If Err.Number <> 0 Then



        Log.Error "Error obtaining language string.", "Failed to obtain ResourceBundle """ & baseFile & """." & VbCrLf &  "Error " & Err.Number & ": " & Err.Source & VbCrLf & Err.Description

        Err.Clear

        

        Set myApp = Nothing

        Set myLoader = Nothing

        Set myLocale = Nothing

        Exit Function

        

      End If 'could not get ResourceBundle

     

      ' Try to get string

      getProperty = myBundle.getString(key)

     

      'Check for exceptions

      If Err.Number <> 0 Then



        Log.Error "Error obtaining language string.", "Failed to obtain property """ & key & """ from """ & baseFile & """." & VbCrLf &  "Error " & Err.Number & ": " & Err.Source & VbCrLf & Err.Description

        Err.Clear

        

        getProperty = Null

        Set myApp = Nothing

        Set myLoader = Nothing

        Set myLocale = Nothing

        Set myBundle = Nothing

        Exit Function

        

      End If 'could not get property string

     

      ' Disable error handling

      On Error GoTo 0



      ' Clear obs

      Set myBundle = Nothing

      Set myLocale = Nothing

      Set myLoader = Nothing

      Set myApp = Nothing



    End Function 'getProperty