[ 
https://issues.apache.org/jira/browse/YARN-4577?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15246170#comment-15246170
 ] 

Sangjin Lee commented on YARN-4577:
-----------------------------------

Thanks for your comments [~vinodkv].

bq. Xuan Gong reminded me offline that we do pass a shared configuration as 
part of serviceInit(). In that case, the solution is simply to pass a private 
cloned Configuration for each of the aux-services?

Yes, that's exactly the scenario under which an aux service gets a reference to 
the shared configuration. Resetting the configuration classloader on a shared 
configuration is a big risk.

I like your idea about creating a copy of the configuration. The only 
implication is that the aux services will then never see any changes made to 
the configuration past {{serviceInit()}}. I don't think that's a deal breaker. 
We could tweak the above code pattern I suggested to achieve this:

{code}
class AuxiliaryServiceWithCustomClassLoader extends AuxiliaryService {
  private final AuxiliaryService wrapped;
  private final ClassLoader customClassLoader;
  private Configuration conf;
  
  public AuxiliaryServiceWithCustomClassLoader(AuxiliaryService s, ClassLoader 
cl) {
    this.wrapped = s;
    this.customClassLoader = cl;
  }

  @Override
  protected void serviceInit(Configuration conf) throws Exception {
    this.conf = new Configuration(conf);
    this.conf.setClassLoader(customClassLoader);
    // call the wrapped service
    callWithCustomClassLoader(wrapped.serviceInit(this.conf));
  }
  ...
  @Override
  protected void serviceStart() throws Exception {
    callWithCustomClassLoader(wrapped.serviceStart());
  }
  ...
  @Override
  public void initializeApplication(ApplicationInitializationContext context) {
    callWithCustomClassLoader(wrapper.initializeApplication(context));
  }
  ...
  private callWithCustomClassLoader(...) {
  }
}
{code}

Then the only thing {{callWithCustomClassLoader()}} needs to deal with is 
setting and unsetting the thread context classloader.

{quote}
In addition to wrapping aux-service API calls under a class-loader, wouldn't it 
suffice to simply have NM make all aux-services API calls in a separate thread 
whose ContextClassLoader is changed to be another custom one that resolves both 
System classes as well as AuxServices classes?
{quote}

If you can dedicate a thread for each aux service, that can work too. However, 
we need to ensure *all* calls to the aux services (*including* the 
{{service*()}} methods) are made on those threads and not on any other thread. 
I think that might make things more complicated than the other way around. The 
{{callWithCustomClassLoader()}} method can be very simple. All it needs to do is

{code}
ClassLoader original = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(customClassLoader);
try {
  // the code that is being wrapped
} finally {
  Thread.currentThread().setContextClassLoader(original);
}
{code}


> Enable aux services to have their own custom classpath/jar file
> ---------------------------------------------------------------
>
>                 Key: YARN-4577
>                 URL: https://issues.apache.org/jira/browse/YARN-4577
>             Project: Hadoop YARN
>          Issue Type: Improvement
>    Affects Versions: 2.8.0
>            Reporter: Xuan Gong
>            Assignee: Xuan Gong
>         Attachments: YARN-4577.1.patch, YARN-4577.2.patch, 
> YARN-4577.20160119.1.patch, YARN-4577.20160204.patch, YARN-4577.3.patch, 
> YARN-4577.3.rebase.patch, YARN-4577.4.patch
>
>
> Right now, users have to add their jars to the NM classpath directly, thus 
> put them on the system classloader. But if multiple versions of the plugin 
> are present on the classpath, there is no control over which version actually 
> gets loaded. Or if there are any conflicts between the dependencies 
> introduced by the auxiliary service and the NM itself, they can break the NM, 
> the auxiliary service, or both.
> The solution could be: to instantiate aux services using a classloader that 
> is different from the system classloader.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to