예제 #1
0
  @Override
  public Enumeration<URL> getResources(final String name) throws IOException {
    if (!getState().isAvailable()) {
      return null;
    }

    if ("META-INF/services/javax.servlet.ServletContainerInitializer".equals(name)) {
      final Collection<URL> list = new ArrayList<>(Collections.list(super.getResources(name)));
      final Iterator<URL> it = list.iterator();
      while (it.hasNext()) {
        final URL next = it.next();
        final File file = Files.toFile(next);
        if (!file.isFile() && NewLoaderLogic.skip(next)) {
          it.remove();
        }
      }
      return Collections.enumeration(list);
    }
    if ("META-INF/services/javax.websocket.ContainerProvider".equals(name)) {
      final Collection<URL> list = new ArrayList<>(Collections.list(super.getResources(name)));
      final Iterator<URL> it = list.iterator();
      while (it.hasNext()) {
        final URL next = it.next();
        final File file = Files.toFile(next);
        if (!file.isFile() && NewLoaderLogic.skip(next)) {
          it.remove();
        }
      }
      return Collections.enumeration(list);
    }
    if ("META-INF/faces-config.xml".equals(name)) { // mojarra workaround
      try {
        if (WebBeansContext.currentInstance() == null
            && Boolean.parseBoolean(
                SystemInstance.get().getProperty("tomee.jsf.ignore-owb", "true"))) {
          final Collection<URL> list = new HashSet<>(Collections.list(super.getResources(name)));
          final Iterator<URL> it = list.iterator();
          while (it.hasNext()) {
            final String fileName = Files.toFile(it.next()).getName();
            if (fileName.startsWith("openwebbeans-" /*jsf|el22*/) && fileName.endsWith(".jar")) {
              it.remove();
            }
          }
          return Collections.enumeration(list);
        }
      } catch (final Throwable th) {
        // no-op
      }
    }
    return URLClassLoaderFirst.filterResources(name, super.getResources(name));
  }
예제 #2
0
  private static Collection<String> extract(final String zip) throws IOException {
    final File tmp = new File(SystemInstance.get().getBase().getDirectory(), TEMP_DIR);
    if (!tmp.exists()) {
      try {
        Files.mkdirs(tmp);
      } catch (Files.FileRuntimeException fre) {
        // ignored
      }
    }

    final File zipFile = new File(realLocation(zip));
    final File extracted = new File(tmp, zipFile.getName().replace(".zip", ""));
    if (extracted.exists()) {
      return list(extracted);
    } else {
      Files.mkdirs(extracted);
    }

    Zips.unzip(zipFile, extracted);
    return list(extracted);
  }
예제 #3
0
  private String[] toFilePaths(final List<String> urls) {
    final List<String> files = new ArrayList<String>();
    for (String url : urls) {
      final File dir = new File(url);
      if (!dir.isDirectory()) {
        continue;
      }

      for (File f : Files.collect(dir, new ClassFilter())) {
        files.add(f.getAbsolutePath());
      }
    }
    return files.toArray(new String[files.size()]);
  }
예제 #4
0
  public static String hash(final Set<URL> urls, final String algo) {
    final Collection<File> files = new ArrayList<File>();

    for (final URL u : urls) {
      final File file = toFile(u);
      if (!file.isDirectory()) {
        files.add(file);
      } else {
        files.addAll(Files.collect(file, TrueFilter.INSTANCE));
      }
    }

    MessageDigest digest = DIGESTS.get(algo);
    if (digest == null) {
      try {
        digest = MessageDigest.getInstance(algo);
      } catch (final NoSuchAlgorithmException e) {
        throw new LoaderRuntimeException(e);
      }
      DIGESTS.put(algo, digest);
    }

    for (final File file : files) {
      if (!file.exists()) {
        continue;
      }

      DigestInputStream is = null;
      try {
        is = new DigestInputStream(new FileInputStream(file), digest);
        IO.copy(is, new NoopOutputStream()); // read the stream
      } catch (final IOException e) {
        // no-op: shouldn't occur here
      } finally {
        IO.close(is);
      }
    }

    final byte[] hash = digest.digest();
    digest.reset();

    final StringBuilder sb = new StringBuilder("");
    for (final byte b : hash) { // hex convertion
      sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
    }

    return sb.toString();
  }
예제 #5
0
  public static void addAdditionalLibraries() throws IOException {
    final File conf = SystemInstance.get().getConf(ADDITIONAL_LIB_CONFIG);
    if (conf == null || !conf.exists()) {
      return;
    }

    final Properties additionalLibProperties = IO.readProperties(conf);

    final List<String> libToCopy = new ArrayList<String>();
    final String toCopy = additionalLibProperties.getProperty(JAR_KEY);
    if (toCopy != null) {
      for (final String lib : toCopy.split(",")) {
        libToCopy.add(realLocation(lib.trim()));
      }
    }
    final String toExtract = additionalLibProperties.getProperty(ZIP_KEY);
    if (toExtract != null) {
      for (final String zip : toExtract.split(",")) {
        libToCopy.addAll(extract(realLocation(zip)));
      }
    }

    final File destination;
    if (additionalLibProperties.containsKey(DESTINATION_KEY)) {
      destination = new File(additionalLibProperties.getProperty(DESTINATION_KEY));
    } else {
      destination =
          new File(SystemInstance.get().getBase().getDirectory(), Embedder.ADDITIONAL_LIB_FOLDER);
    }
    if (!destination.exists()) {
      Files.mkdirs(destination);
    }

    for (final String lib : libToCopy) {
      copy(new File(lib), destination);
    }
  }
예제 #6
0
  public void enhance(@Observes final BeforeDeploymentEvent event) {
    if (enhancerMethod == null) {
      LOGGER.debug("OpenJPA is not available so no deploy-time enhancement will be done");
      return;
    }

    // find persistence.xml
    final Map<String, List<String>> classesByPXml = new HashMap<String, List<String>>();
    final List<URL> usedUrls = new ArrayList<URL>(); // for fake classloader
    for (URL url : event.getUrls()) {
      final File file = URLs.toFile(url);
      if (file.isDirectory()) {
        final String pXmls = getWarPersistenceXml(url);
        if (pXmls != null) {
          feed(classesByPXml, pXmls);
        }

        usedUrls.add(url);
      } else if (file.getName().endsWith(".jar")) {
        try {
          final JarFile jar = new JarFile(file);
          ZipEntry entry = jar.getEntry(META_INF_PERSISTENCE_XML);
          if (entry != null) {
            final String path = file.getAbsolutePath();
            final File unpacked =
                new File(path.substring(0, path.length() - 4) + TMP_ENHANCEMENT_SUFFIX);
            JarExtractor.extract(file, unpacked);

            // replace jar by folder url since otherwise enhancement doesn't work
            usedUrls.add(unpacked.toURI().toURL());

            feed(classesByPXml, new File(unpacked, META_INF_PERSISTENCE_XML).getAbsolutePath());
          }
        } catch (IOException e) {
          // ignored
        }
      } else {
        usedUrls.add(url);
      }
    }

    // enhancement

    final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
    final ClassLoader fakeClassLoader =
        new URLClassLoaderFirst(
            usedUrls.toArray(new URL[usedUrls.size()]), event.getParentClassLoader());

    Thread.currentThread().setContextClassLoader(fakeClassLoader);
    try {
      for (Map.Entry<String, List<String>> entry : classesByPXml.entrySet()) {
        final Properties opts = new Properties();
        opts.setProperty(PROPERTIES_FILE_PROP, entry.getKey());

        final Object optsArg;
        try {
          optsArg = optionsConstructor.newInstance(opts);
        } catch (Exception e) {
          LOGGER.debug("can't create options for enhancing");
          return;
        }

        LOGGER.info("enhancing url(s): " + Arrays.asList(event.getUrls()));
        try {
          enhancerMethod.invoke(null, toFilePaths(entry.getValue()), optsArg);
        } catch (Exception e) {
          LOGGER.warning("can't enhanced at deploy-time entities", e);
        }
      }
    } finally {
      Thread.currentThread().setContextClassLoader(tccl);
      usedUrls.clear();
    }

    // clean up extracted jars and replace jar to keep consistent classloading
    for (Map.Entry<String, List<String>> entry : classesByPXml.entrySet()) {
      final List<String> values = entry.getValue();
      for (String rawPath : values) {
        if (rawPath.endsWith(TMP_ENHANCEMENT_SUFFIX + "/")
            || rawPath.endsWith(TMP_ENHANCEMENT_SUFFIX)) {
          final File dir = new File(rawPath);
          final File file =
              new File(
                  rawPath.substring(0, rawPath.length() - TMP_ENHANCEMENT_SUFFIX.length() - 1)
                      + ".jar");
          if (file.exists()) {
            String name = dir.getName();
            name = name.substring(0, name.length() - TMP_ENHANCEMENT_SUFFIX.length()) + ".jar";

            final File target = new File(dir.getParentFile(), name);
            try { // override existing jar otherwise classloading is broken in tomee
              Files.delete(file);
              JarCreator.jarDir(dir, target);
            } catch (final IOException e) {
              LOGGER.error("can't repackage enhanced jar file " + file.getName());
            }
            Files.delete(dir);
          }
        }
      }
      values.clear();
    }

    classesByPXml.clear();
  }