code: public void defineProperty(String propertyName, Class<?> clazz,
                                 int attributes)
      {
          int length = propertyName.length();
          if (length == 0) throw new IllegalArgumentException();
          char[] buf = new char[3 + length];
          propertyName.getChars(0, length, buf, 3);
          buf[3] = Character.toUpperCase(buf[3]);
          buf[0] = 'g';
          buf[1] = 'e';
          buf[2] = 't';
          String getterName = new String(buf);
          buf[0] = 's';
          String setterName = new String(buf);
  
          Method[] methods = FunctionObject.getMethodList(clazz);
          Method getter = FunctionObject.findSingleMethod(methods, getterName);
          Method setter = FunctionObject.findSingleMethod(methods, setterName);
          if (setter == null)
              attributes |= ScriptableObject.READONLY;
          defineProperty(propertyName, null, getter,
                         setter == null ? null : setter, attributes);
      }
docs: Define a JavaScript property with getter and setter side effects.
  
  If the setter is not found, the attribute READONLY is added to
  the given attributes. <p>
  
  The getter must be a method with zero parameters, and the setter, if
  found, must be a method with one parameter.<p>
  
  @param propertyName the name of the property to define. This name
  also affects the name of the setter and getter
  to search for. If the propertyId is "foo", then
  <code>clazz</code> will be searched for "getFoo"
  and "setFoo" methods.
  @param clazz the Java class to search for the getter and setter
  @param attributes the attributes of the JavaScript property
  @see org.mozilla.javascript.Scriptable#put(String, Scriptable, Object)