Image

Imagemihhon wrote in Imageru_java

почему в sun решили что через reflection api должны быть недоступны имена параметров метода?

Их судя по всему не сохраняют в байт-коде в отличие от имён методов, например


Есть библиотека - dll, в методы передаётся до пяти десятков параметров, при некорректных входных данных процесс убивается - jvmcrush или метод возвращает код, который содержит номер некорректного параметра + код ошибки. Поэтому надо напечатать всю инфо, переданную в метод (чтоб знать отчего накрылся процесс) и если процесс не накрылся вынуть инфо из кода ошибки (данные перед вызовом проверяются, но никто не совершенен..., и ошибки могут быть в самой библиотеке)

задача: получить доступ к переданным в метод параметрам и именам параметров чтоб:
А. распечатать перед вызовом
Б. очибочный параметр

сейчас это делается с помощью методологии copy/paste параметров метода + regexp (поэтомy быстро), но код не сильно читабельный получается - вызов метода может занять несколько сотен строк ...

Хочется сократить количество строк ... чтоб код лучше читалсо. Я смотрел аспекты, но там надо явно объявлять все параметры метода, к которым хочешь обратиться - тот же самый гемор, только разнсённый в несколько мест.
Было бы можно перехватить вызов метода и пробежаться по параметрам/их именам/ перед вызовом и в блоке обработки исключения - было бы просто прекрасно. Не приходят в головы идеи как это сделать

пример кода

    double[][] stats = FincadUtils.getAllStatistics(22);
    
    // print before to call
    if (log.isInfoEnabled()) {
      StringBuffer sb = new StringBuffer();
      sb.append("settlementDate=").append(Util.getDBDate(settlementDate));
      sb.append(", effectiveDate=").append(Util.getDBDate(adjReset.effectiveDate));
      sb.append(", terminatingDate=").append(Util.getDBDate(adjReset.terminatingDate));
      sb.append(", d_f_cpn=").append(d_f_cpn);
      sb.append(", d_l_cpn=").append(d_l_cpn);
      sb.append(", couponAndResetFrequency=").append(couponAndResetFrequency);
      sb.append(", cashflows=");
      FincadUtils.appendToStringToStrBuf(sb, cf, // cf - 2dim array, this method prints it using additional info
        IFields.CASHFLOW_VAR_FRN_FIELD_NAMES, IFields.CASHFLOW_VAR_FRN_FIELD_TYPES);
      sb.append(", shortLong=").append(shortLong);
      sb.append(", couponCompoundingMethod=").append(couponCompoundingMethod);
      sb.append(", couponDayCount=").append(couponDayCount);
      sb.append(", couponBusinessDay=").append(couponBusinessDay);
      sb.append(", resetDayCount=").append(resetDayCount);
      sb.append(", resetBusinessDay=").append(resetBusinessDay);
      sb.append(", daysPriorReset=").append(daysPriorReset);
      sb.append(", stubMethod=").append(stubMethod);
      sb.append(", compoundedResetMargin=").append(compoundedResetMargin);
      sb.append(", resetMargin=").append(resetMargin);
      sb.append(", resets=").append(Arrays.deepToString(adjReset.resets));
      sb.append(", yieldInterpolationMethod=").append(yieldInterpolationMethod);
      sb.append(", discountFactors=").append(Arrays.deepToString(discountFactors));
      sb.append(", discountFactors=").append(Arrays.deepToString(discountFactors));
      sb.append(", bankHolidays=");
      FincadUtils.appendToStringToStrBuf(sb, bankHolidays, 
        IFields.BANK_HOLIDAY_LIST_NAMES, IFields.BANK_HOLIDAY_LIST_TYPES);
      sb.append(", stats=").append(stats);
      log.info("calling aaFRN2_dgen : " + sb.toString());
    } 
    
    // method call 
    double[] result = null;
    try {
      result = ShowAll.aaFRN2_dgen_java(
        settlementDate,
        adjReset.effectiveDate,
        adjReset.terminatingDate,
        d_f_cpn, 
        d_l_cpn, 
        couponAndResetFrequency,
        cf,
        shortLong,
        couponCompoundingMethod,
        couponDayCount, 
        couponBusinessDay,
        resetDayCount,
        resetBusinessDay,
        daysPriorReset,
        stubMethod,
        compoundedResetMargin, 
        resetMargin,
        adjReset.resets,
        yieldInterpolationMethod,
        discountFactors,
        discountFactors, 
        bankHolidays,
        stats);
    }
    catch (Exception e) { FincadUtils.throwRtDllError(); }
    
    // checks return code
    // If you were to get a four/five digit code, you would interpret 
    // it the following way:
    // Example: error code: 17392
    // 1) The last three digits correspond to the restriction ID (392).
    // 2) The first two digits (17) correspond to the argument position. 
    // This means that argument 17 is violating restriction ID 392 - "must be > effective date, < last date in discount factor curve".
    if (FincadResultHelper.fincadError(result, FincadResultHelper.FINCAD_ARRAY)) {  

      // throws an exception, error message will contain "name=value" of the erronous param
      FincadResultHelper.throwFincadError(result, "aaFRN2_dgen", 
        new String[] {
          "settlementDate",
          "effectiveDate",
          "terminatingDate",
          "d_f_cpn", 
          "d_l_cpn", 
          "couponAndResetFrequency",
          "cf",
          "shortLong",
          "couponCompoundingMethod",
          "couponDayCount", 
          "couponBusinessDay",
          "resetDayCount",
          "resetBusinessDay",
          "daysPriorReset",
          "stubMethod",
          "compoundedResetMargin", 
          "resetMargin",
          "resets",
          "yieldInterpolationMethod",
          "discountFactors",
          "discountFactors", 
          "bankHolidays",
          "stats"}, 
        new Object[] {settlementDate,
                      adjReset.effectiveDate,
                      adjReset.terminatingDate,
                      d_f_cpn, 
                      d_l_cpn, 
                      couponAndResetFrequency,
                      cf,
                      shortLong,
                      couponCompoundingMethod,
                      couponDayCount, 
                      couponBusinessDay,
                      resetDayCount,
                      resetBusinessDay,
                      daysPriorReset,
                      stubMethod,
                      compoundedResetMargin, 
                      resetMargin,
                      adjReset.resets,
                      yieldInterpolationMethod,
                      discountFactors,
                      discountFactors, 
                      bankHolidays,
                      stats}, 
        FincadResultHelper.FINCAD_ARRAY);
    }
    FincadResultHelper.checkResultArrayLength("aaFRN2_dgen", result, 25);



upd: нашёлся исходник ShowAll, в котором объявлены нативные методы, который, видимо, сгенерён на базе си-шных хэдеров, но там имена переменных нелепые, надо ручками править, неохота. а так пропарсить этот исходник и половина дела сделана


public native static double[] aaFRN2_dgen_java (double d_v, double d_e, double d_t, double d_f_cpn, double d_l_cpn, int freq_pay_reset, double[][] frn_tbl, int position, 
               int cmpd_meth, int acc_pay, int d_rul_pay, int acc_rt, int d_rul_reset, int reset_mktdays, int stub_method, double mgn_pay, 
               double mgn_reset, double[][] fixed_reset_tbl, int intrp, double[][] df_crv_acc, double[][] df_crv_disc, double[][] hl, double[][] stat);