diff --git a/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/PluginServiceImpl.java b/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/PluginServiceImpl.java index 69b79047916..162d4bc394a 100644 --- a/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/PluginServiceImpl.java +++ b/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/PluginServiceImpl.java @@ -19,7 +19,10 @@ import jakarta.persistence.criteria.Predicate; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; @@ -96,6 +99,11 @@ public void deletePlugins(Set ids) { if (jarFile.exists()) { FileUtils.delete(jarFile); } + // removing jar files that are dependencies for the plugin + File otherLibDir = new File(getOtherLibDir(plugin.getJarFilePath())); + if (otherLibDir.exists()) { + FileUtils.deleteDirectory(otherLibDir); + } // delete metadata metadataDao.deleteById(plugin.getId()); } catch (IOException e) { @@ -108,6 +116,16 @@ public void deletePlugins(Set ids) { loadJarToClassLoader(); } + /** + * get the directory where the JAR files dependent on the plugin are saved + * + * @param pluginJarPath jar file path + * @return lib dir + */ + private String getOtherLibDir(String pluginJarPath) { + return pluginJarPath.substring(0, pluginJarPath.lastIndexOf(".")); + } + @Override public void updateStatus(PluginMetadata plugin) { Optional pluginMetadata = metadataDao.findById(plugin.getId()); @@ -274,8 +292,9 @@ private void loadJarToClassLoader() { System.gc(); List plugins = metadataDao.findPluginMetadataByEnableStatusTrue(); for (PluginMetadata metadata : plugins) { - URL url = new File(metadata.getJarFilePath()).toURI().toURL(); - pluginClassLoaders.add(new URLClassLoader(new URL[]{url}, Plugin.class.getClassLoader())); + List urls = loadLibInPlugin(metadata.getJarFilePath()); + urls.add(new File(metadata.getJarFilePath()).toURI().toURL()); + pluginClassLoaders.add(new URLClassLoader(urls.toArray(new URL[0]), Plugin.class.getClassLoader())); } } catch (MalformedURLException e) { log.error("Failed to load plugin:{}", e.getMessage()); @@ -285,6 +304,42 @@ private void loadJarToClassLoader() { } } + /** + * loading other JAR files that are dependencies for the plugin + * + * @param pluginJarPath jar file path + * @return urls + */ + @SneakyThrows + private List loadLibInPlugin(String pluginJarPath) { + File libDir = new File(getOtherLibDir(pluginJarPath)); + FileUtils.forceMkdir(libDir); + List libUrls = new ArrayList<>(); + try (JarFile jarFile = new JarFile(pluginJarPath)) { + Enumeration entries = jarFile.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + File file = new File(libDir, entry.getName()); + if (!entry.isDirectory() && entry.getName().endsWith(".jar")) { + if (!file.getParentFile().exists()) { + FileUtils.createParentDirectories(file); + } + try (InputStream in = jarFile.getInputStream(entry); + OutputStream out = new FileOutputStream(file)) { + byte[] buffer = new byte[4096]; + int len; + while ((len = in.read(buffer)) != -1) { + out.write(buffer, 0, len); + } + libUrls.add(file.toURI().toURL()); + out.flush(); + } + } + } + } + return libUrls; + } + @Override public void pluginExecute(Class clazz, Consumer execute) { for (URLClassLoader pluginClassLoader : pluginClassLoaders) { diff --git a/manager/src/main/resources/application.yml b/manager/src/main/resources/application.yml index 619e52b1c8d..33ad559a274 100644 --- a/manager/src/main/resources/application.yml +++ b/manager/src/main/resources/application.yml @@ -33,7 +33,10 @@ spring: exclude: org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration, org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration freemarker: enabled: false - + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB management: health: @@ -81,7 +84,7 @@ spring: eclipselink: logging: level: SEVERE - + flyway: enabled: true clean-disabled: true @@ -89,9 +92,9 @@ spring: baseline-version: 1 locations: - classpath:db/migration/{vendor} - + mail: - # Mail server address, eg: qq-mailbox is smtp.qq.com, qq-exmail is smtp.exmail.qq.com + # Mail server address, eg: qq-mailbox is smtp.qq.com, qq-exmail is smtp.exmail.qq.com host: smtp.qq.com username: tancloud@qq.com # Attention this is not email account password, this requires an email authorization code diff --git a/plugin/pom.xml b/plugin/pom.xml index 461adca6704..023225ceb8f 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -37,8 +37,32 @@ org.apache.hertzbeat hertzbeat-common + provided + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + src/main/resources/assembly/assembly.xml + + + + + make-assembly + package + + single + + + + + + diff --git a/plugin/src/main/resources/assembly/assembly.xml b/plugin/src/main/resources/assembly/assembly.xml new file mode 100644 index 00000000000..2b5008142f7 --- /dev/null +++ b/plugin/src/main/resources/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + jar-with-lib + + jar + + false + + + /lib + false + runtime + + ${project.groupId}:${project.artifactId} + + + + + + ${project.build.outputDirectory} + / + + +