This project has retired. For details please refer to its Attic page.
Source code
001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.reef.runtime.yarn;
020
021import net.jcip.annotations.Immutable;
022import org.apache.commons.lang.StringUtils;
023import org.apache.hadoop.yarn.conf.YarnConfiguration;
024import org.apache.reef.runtime.common.files.RuntimeClasspathProvider;
025import org.apache.reef.util.OSUtils;
026
027import javax.inject.Inject;
028import java.util.List;
029import java.util.logging.Level;
030import java.util.logging.Logger;
031
032/**
033 * Access to the classpath according to the REEF file system standard.
034 */
035@Immutable
036public final class YarnClasspathProvider implements RuntimeClasspathProvider {
037  private static final Logger LOG = Logger.getLogger(YarnClasspathProvider.class.getName());
038  private static final Level CLASSPATH_LOG_LEVEL = Level.FINE;
039
040  private static final String YARN_TOO_OLD_MESSAGE = "The version of YARN you are using is too old to support classpath assembly. Reverting to legacy method.";
041  private static final String HADOOP_CONF_DIR = OSUtils.formatVariable("HADOOP_CONF_DIR");
042  private static final String HADOOP_HOME = OSUtils.formatVariable("HADOOP_HOME");
043  private static final String HADOOP_COMMON_HOME = OSUtils.formatVariable("HADOOP_COMMON_HOME");
044  private static final String HADOOP_YARN_HOME = OSUtils.formatVariable("HADOOP_YARN_HOME");
045  private static final String HADOOP_HDFS_HOME = OSUtils.formatVariable("HADOOP_HDFS_HOME");
046  private static final String HADOOP_MAPRED_HOME = OSUtils.formatVariable("HADOOP_MAPRED_HOME");
047
048  // Used when we can't get a classpath from YARN
049  private static final String[] LEGACY_CLASSPATH_LIST = new String[]{
050      HADOOP_CONF_DIR,
051      HADOOP_HOME + "/*",
052      HADOOP_HOME + "/lib/*",
053      HADOOP_COMMON_HOME + "/*",
054      HADOOP_COMMON_HOME + "/lib/*",
055      HADOOP_YARN_HOME + "/*",
056      HADOOP_YARN_HOME + "/lib/*",
057      HADOOP_HDFS_HOME + "/*",
058      HADOOP_HDFS_HOME + "/lib/*",
059      HADOOP_MAPRED_HOME + "/*",
060      HADOOP_MAPRED_HOME + "/lib/*",
061      HADOOP_HOME + "/etc/hadoop",
062      HADOOP_HOME + "/share/hadoop/common/*",
063      HADOOP_HOME + "/share/hadoop/common/lib/*",
064      HADOOP_HOME + "/share/hadoop/yarn/*",
065      HADOOP_HOME + "/share/hadoop/yarn/lib/*",
066      HADOOP_HOME + "/share/hadoop/hdfs/*",
067      HADOOP_HOME + "/share/hadoop/hdfs/lib/*",
068      HADOOP_HOME + "/share/hadoop/mapreduce/*",
069      HADOOP_HOME + "/share/hadoop/mapreduce/lib/*"
070  };
071  private final List<String> classPathPrefix;
072  private final List<String> classPathSuffix;
073
074  @Inject
075  YarnClasspathProvider(final YarnConfiguration yarnConfiguration) {
076    boolean needsLegacyClasspath = false; // will be set to true below whenever we encounter issues with the YARN Configuration
077    final ClassPathBuilder builder = new ClassPathBuilder();
078
079    try {
080      // Add the classpath actually configured on this cluster
081      final String[] yarnClassPath = yarnConfiguration.getTrimmedStrings(YarnConfiguration.YARN_APPLICATION_CLASSPATH);
082      if (null == yarnClassPath || yarnClassPath.length == 0) {
083        needsLegacyClasspath = true;
084      } else {
085        builder.addAll(yarnClassPath);
086      }
087      final String[] yarnDefaultClassPath = YarnConfiguration.DEFAULT_YARN_CROSS_PLATFORM_APPLICATION_CLASSPATH;
088      if (null == yarnDefaultClassPath || yarnDefaultClassPath.length == 0) {
089        LOG.log(Level.SEVERE, "YarnConfiguration.DEFAULT_YARN_CROSS_PLATFORM_APPLICATION_CLASSPATH is empty. This indicates a broken cluster configuration");
090        needsLegacyClasspath = true;
091      } else {
092        builder.addAll(yarnDefaultClassPath);
093      }
094    } catch (final NoSuchFieldError e) {
095      // This means that one of the static fields above aren't actually in YarnConfiguration.
096      // The reason for that is most likely that we encounter a really old version of YARN.
097      needsLegacyClasspath = true;
098      LOG.log(Level.SEVERE, YARN_TOO_OLD_MESSAGE);
099    }
100
101    if (needsLegacyClasspath) {
102      builder.addAll(LEGACY_CLASSPATH_LIST);
103    }
104
105    this.classPathPrefix = builder.getPrefixAsImmutableList();
106    this.classPathSuffix = builder.getSuffixAsImmutableList();
107    this.logClasspath();
108  }
109
110  @Override
111  public List<String> getDriverClasspathPrefix() {
112    return this.classPathPrefix;
113  }
114
115  @Override
116  public List<String> getDriverClasspathSuffix() {
117    return this.classPathSuffix;
118  }
119
120  @Override
121  public List<String> getEvaluatorClasspathPrefix() {
122    return this.classPathPrefix;
123  }
124
125  @Override
126  public List<String> getEvaluatorClasspathSuffix() {
127    return this.classPathSuffix;
128  }
129
130
131  private void logClasspath() {
132    if (LOG.isLoggable(CLASSPATH_LOG_LEVEL)) {
133      final StringBuilder message = new StringBuilder("Classpath:\n\t");
134      message.append(StringUtils.join(classPathPrefix, "\n\t"));
135      message.append("\n--------------------------------\n\t");
136      message.append(StringUtils.join(classPathSuffix, "\n\t"));
137      LOG.log(CLASSPATH_LOG_LEVEL, message.toString());
138    }
139  }
140}