Пример #1
0
  private LibSearchResult searchLibrary(String libname, Version requiredVersion) {
    LibSearchResult searchResult = new LibSearchResult();

    for (Location l : locations) {
      Logger.info("Checking " + libname + " from " + l + "...");

      List<String> pathsToCheck = new ArrayList<String>();
      boolean useLoadLibrary = false;
      boolean searchEvenAfterFound = !JUST_DO_SIMPLE_LOAD_LIBRARY;
      switch (l) {
        case LIBPATH:
          {
            pathsToCheck.add(libname);
            String libnameWithDataModel = libnameWithDataModel(libname);
            if (libnameWithDataModel != null) {
              pathsToCheck.add(libnameWithDataModel);
            }
            useLoadLibrary = true;
            break;
          }
        case CACHE:
          {
            String filename = properties.get(libname);
            if (filename == null) {
              continue;
            }

            // when search is enabled, we might skip it if cache has information about previously
            // loaded library and last search was less than SEARCH_LIB_FREQUENCY_INTERVAL ago
            Date lastSearchDate = properties.getLastSeach(libname);

            searchEvenAfterFound =
                lastSearchDate == null
                    || (new Date().getTime() - lastSearchDate.getTime()
                        > SEARCH_LIB_FREQUENCY_INTERVAL);

            pathsToCheck.add(filename);
            // this is kind of hack, but it does not require different checks between win/unix
            // we say that library was loaded from LIBPATH location when its path starts from
            // library simple name
            useLoadLibrary = filename.startsWith(libname);
            break;
          }
        case DOWNLOAD:
          {
            Logger.info("Downloading " + libname + " from NCBI...");
            LibDownloadResult downloadResult;
            if (!mocksEnabled) {
              downloadResult = download(libname);
            } else if (mockDownloadStatus == null) {
              throw new RuntimeException("mockDownloadStatus must be set when mocks enabled");
            } else {
              downloadResult = new LibDownloadResult();
              downloadResult.status = mockDownloadStatus;
              downloadResult.savedPath = "/some/path/" + libname;
            }
            if (downloadResult.status != DownloadManager.DownloadResult.SUCCESS) {
              Logger.warning("Failed to download " + libname + " from NCBI");
              if (downloadResult.status == DownloadManager.DownloadResult.UNSUPPORTED_OS) {
                searchResult.failCause = new UnsupportedArchCause();
              } else {
                searchResult.failCause = new ConnectionProblemCause();
              }
              continue;
            }
            Logger.info("Downloaded " + libname + " from NCBI");
            Logger.fine("Checking " + libname + " library...");

            pathsToCheck.add(downloadResult.savedPath);
            break;
          }
        default:
          {
            String name[] = mapLibraryName(libname);
            Logger.finest("System.mapLibraryName(" + libname + ") = " + name[0]);

            LibPathIterator it = new LibPathIterator(l, name);
            while (true) {
              String filename = it.nextName();
              if (filename == null) {
                break;
              }

              pathsToCheck.add(filename);
            }
            break;
          }
      }

      boolean foundInLocation = false;
      for (String path : pathsToCheck) {
        Version v;
        if (!mocksEnabled) {
          v = checkLibraryVersion(libname, path, useLoadLibrary);
        } else if (mockLocationVersions == null) {
          throw new RuntimeException("mockLocationVersions must be set when mocks enabled");
        } else {
          v = mockLocationVersions.get(l);
        }
        if (v == null) {
          continue;
        }

        foundInLocation = true;

        boolean versionFits = v.isCompatible(requiredVersion) && v.compareTo(requiredVersion) >= 0;
        // replace a found version if either:
        // a) none was previously found
        // b) found version which fits requirements and it is higher than previously found
        // c) found version version which fits requirements while previously found one does not
        if (searchResult.path == null
            || (versionFits && (v.compareTo(searchResult.version) > 0)
                || !searchResult.versionFits)) {
          searchResult.versionFits = versionFits;
          searchResult.location = l;
          searchResult.version = v;
          searchResult.path = path;
        }

        if (searchResult.versionFits && !searchEvenAfterFound) {
          break;
        }
      }

      if (l == Location.DOWNLOAD) {
        // when we downloaded something that either can't be loaded or does not fit our requirements
        // or we just overwrote our best found library and cannot load it
        if (!searchResult.versionFits
            || (!foundInLocation && searchResult.path.equals(pathsToCheck.get(0)))) {
          searchResult.versionFits = false;
          searchResult.location = l;
          searchResult.version = null;
          searchResult.path = pathsToCheck.get(0);
        }
      }

      if (searchResult.version != null && searchResult.version.isCompatible(requiredVersion)) {
        Version latestVersion = getLatestVersion(libname);
        // if we don't know the latest version, then we might stop the search if
        // found version is okay and searchEvenAfterFound == false
        if (latestVersion == null
            && searchResult.version.compareTo(requiredVersion) >= 0
            && !searchEvenAfterFound) {
          break;
        }
        // if we know the latest version, then we should search until find it
        if (latestVersion != null && searchResult.version.compareTo(requiredVersion) >= 0) {
          break;
        }
      }
    }

    boolean downloadEnabled = Arrays.asList(locations).contains(Location.DOWNLOAD);

    if (searchResult.failCause == null && !downloadEnabled) {
      searchResult.failCause = new DownloadDisabledCause();
    }

    return searchResult;
  }
Пример #2
0
  /**
   * Loads the system library by finding it by iterating the location array. Try to download it from
   * NCBI if not found.
   *
   * <p>Will throw LibraryLoadError when failed.
   */
  void loadLibrary(String libname) {
    Version requiredVersion = getRequiredVersion(libname);
    boolean updateCache = Arrays.asList(locations).contains(Location.CACHE);

    Logger.fine("Searching for " + libname + " library...");
    try {
      LibSearchResult searchResult = searchLibrary(libname, requiredVersion);

      if (searchResult.path == null) {
        throw new LibraryNotFoundError(
            libname, "No installed library was found", searchResult.failCause);
      }

      Logger.fine("Found " + libname + " library");

      String libpath = searchResult.path;
      Logger.info("Loading " + libname + "...");
      try {
        if (!mocksEnabled) {
          if (libpath.startsWith(libname)) {
            System.loadLibrary(libpath);
          } else {
            System.load(libpath);
          }
        } else if (mockLoadException != null) {
          throw mockLoadException;
        }
      } catch (Throwable e) {
        if (searchResult.location != Location.DOWNLOAD) {
          throw new LibraryLoadError(
              libname, "Failed to load found library " + libpath, new JvmErrorCause(e));
        }

        throw new LibraryLoadError(
            libname,
            "No installed library was found and downloaded library '"
                + libpath
                + "' cannot be loaded",
            new JvmErrorCause(e),
            "Please install ngs and ncbi-vdb manually:"
                + " https://github.com/ncbi/ngs/wiki/Downloads"
                + " or write to \"[email protected]\" if problems persist");
      }
      Logger.fine("Loaded " + libname + " library");

      Logger.fine("Checking library " + libname + " version...");
      String v;
      if (!mocksEnabled) {
        v = LibVersionChecker.getLoadedVersion(libname);
      } else {
        v = mockLoadedLibraryVersion;
      }
      if (v == null) {
        throw new LibraryLoadError(
            libname, "Failed to retrieve loaded library's version", new InvalidLibraryCause());
      }
      Version loadedVersion = new Version(v);
      if (loadedVersion.compareTo(requiredVersion) < 0
          || !loadedVersion.isCompatible(requiredVersion)) {
        Logger.fine(
            "Library version is not compatible. Required: "
                + requiredVersion.toSimpleVersion()
                + " loaded: "
                + loadedVersion.toSimpleVersion());
        LibraryLoadCause failCause = searchResult.failCause;
        if (searchResult.location == Location.DOWNLOAD || failCause == null) {
          failCause =
              (loadedVersion.compareTo(requiredVersion) < 0)
                  ? new PrereleaseReqLibCause()
                  : new OutdatedJarCause();
        }
        throw new LibraryIncompatibleVersionError(
            libname, "Library is incompatible", libpath, failCause);
      }
      Logger.fine(
          "Library "
              + libname
              + " was loaded successfully."
              + " Version = "
              + loadedVersion.toSimpleVersion());

      if (updateCache) {
        properties.loaded(libname, searchResult.version.toSimpleVersion(), libpath);

        if (searchResult.location != Location.CACHE) {
          properties.setLastSearch(libname);
        }
      }
    } catch (LibraryLoadError e) {
      if (updateCache) {
        properties.notLoaded(libname);
      }
      Logger.warning("Loading of " + libname + " library failed");
      throw e;
    } finally {
      if (updateCache) {
        properties.store();
      }
    }
  }