com.thoughtworks.xstream.XStreamException: Can't serialize proxies

The following class is implemented in a module and I think it cannot be serialized because of patientCalculationService field. The class is used in CohortDefinition classes that run the calculation when they are evaluated.

I would like to keep using @Autowired and not something like Context.getService(PatientCalculationService.class), is it possible to do?

public abstract class AbstractPatientCalculation extends BaseCalculation
    implements PatientCalculation {

  @Autowired private PatientCalculationService patientCalculationService;

  protected static CalculationResultMap passing(CalculationResultMap results) {
    CalculationResultMap ret = new CalculationResultMap();
    for (Map.Entry<Integer, CalculationResult> e : results.entrySet()) {
      ret.put(e.getKey(), new BooleanResult(ResultUtil.isTrue(e.getValue()), null));
    }
    return ret;
  }

  protected CalculationResultMap calculate(
      PatientCalculation calculation,
      Collection<Integer> cohort,
      PatientCalculationContext calculationContext) {
    return patientCalculationService.evaluate(cohort, calculation, calculationContext);
  }
}

Here is an example of how it is being used:

Here is the stack trace https://pastebin.com/bMPQ6hcP

1 Like

@yassin , the stack trace in the link and the use-case described seem not to correlate. Any ways, a simple thought on this is, what happens when you implement

of-course bearing in mind that you may have to transform

into a spring managed bean to use it.

Thanks @ruhanga

The class OnArtForMoreThanXmonthsCalcultion from the example is annotated with @Component.

Is that what you meant?

That’s cool then @yassin , however where as this

@Autowired private PatientCalculationService patientCalculationService;

may be possible, I have seen there are constraints that will break as can be traced in these lines .

I think in this case the service is injected correctly:

  @PostConstruct
  public void init() {
    System.out.println(patientCalculationService);
  }
 // org.openmrs.calculation.patient.PatientCalculationServiceImpl@e4806c6

But then it fails when starting the module with the exception in the stack trace.

Would it be possible for you to try to run the module?

Sure @yassin , gona try this out and will get back to you but, any worthwhile reason to go this far :slightly_smiling_face:?

@ruhanga The reason is unit testing. I need to mock the patientCalculationService.

With Context.getService(PatientCalculationService.class). I can’t use ContextMockHelper because it is deprecated so I am forced to use PowerMockito to be able to mock the static method.

I would prefer not to use PowerMockito if possible.

Sorry for the late response here @yassin , are you still being blocked with this approach?

Trying out with @Autowired in place of Context.get....Service returned several NullPointerExceptions in the test environment for me. I am thinking like you mentioned PowerMockito may do the trick.