3

I have this class:

@Transactional
@Repository("reportManagementDAO")
public class ReportManagementDAOImpl implements ReportManagementDAO,
        Serializable{
@Autowired
private SessionFactory getSessionFactory;

public SessionFactory getSessionFactory(){
   return sessionFactory;
}

public void setSessionFactory(SessionFactory sessionFactory){
  this.sessionFactory = sessionFactory;
}

 class ReportWork extends AbstractReportWork{

 }
}//

abstract class AbstractReportWork extends RCDStoreProcedureWork {

   void doReport() {
     //How can I access to: ReportManagementDAOImpl.getSessionFactory()
     //using reflection, for example: 
     //Class<?> type = getClass().getEnclosingClass();
   }
}

How can I access to: ReportManagementDAOImpl.getSessionFactory(), by external class using reflection????

wilmardma
  • 31
  • 1
  • 1
    @david-basarab Can you people read the damn question before marking as duplicate? This has nothing to do with accessing non-visible classes. The word _external_ here means _outer_ class. No other similarities. – kaqqao Mar 23 '17 at 15:20

1 Answers1

2

If AbstractReportWork is also nested inside ReportManagementDAOImpl and is not static, you can just get the current outer instance via ReportManagementDAOImpl.this.

If AbstractReportWork is not nested inside ReportManagementDAOImpl, what you're trying to do is (while possible) a terrible idea because you're introducing a hidden (and extremely unusual) requirement that inheritors of AbstractReportWork must be nested classes. This is nothing short of a land mine, so don't do it.

Here are better alternatives:

  1. If possible (i.e. if it's all stateless), @Autowire SessionFactory into the class where you need it (instead of getting it from the outer classes, or getting it manually from anywhere for that matter)
  2. Otherwise, pass an instance of ReportManagementDAO or SessionFactory to ReportWork if it is needed (possibly by making doReport() accept it: doReport(SessionFactory sessFactory){...} or by making the constructor accept it: ReportWork(SessionFactory sessFactory) {...})

If you really want to watch the world burn, reflectively get the enclosing instance:

Field this$0 = this.getClass().getDeclaredField("this$0");
//not sure if this$0.setAccessible(true); is required
ReportManagementDAO enclosing = (ReportManagementDAO) this$0.get(this);
enclosing.getSessionFactory();

But be warned, this is a hack that can and will break in future Java versions because the this$0 field is in no way a part of the documented API.

kaqqao
  • 12,984
  • 10
  • 64
  • 118