{"id":20885659,"url":"https://github.com/pf4j/pf4j-update","last_synced_at":"2025-04-12T06:08:23.954Z","repository":{"id":18147937,"uuid":"21241602","full_name":"pf4j/pf4j-update","owner":"pf4j","description":"Update mechanism for PF4J","archived":false,"fork":false,"pushed_at":"2024-10-12T16:33:58.000Z","size":422,"stargazers_count":68,"open_issues_count":9,"forks_count":41,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-12T06:08:14.158Z","etag":null,"topics":["java","modularity","pf4j","plugins","update"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pf4j.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-06-26T13:29:34.000Z","updated_at":"2025-03-21T07:37:12.000Z","dependencies_parsed_at":"2025-01-15T03:52:33.458Z","dependency_job_id":"5813abeb-dfab-40da-9f72-5f5bb3e7372c","html_url":"https://github.com/pf4j/pf4j-update","commit_stats":null,"previous_names":["decebals/pf4j-update"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pf4j%2Fpf4j-update","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pf4j%2Fpf4j-update/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pf4j%2Fpf4j-update/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pf4j%2Fpf4j-update/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pf4j","download_url":"https://codeload.github.com/pf4j/pf4j-update/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248525141,"owners_count":21118619,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","modularity","pf4j","plugins","update"],"created_at":"2024-11-18T08:14:08.278Z","updated_at":"2025-04-12T06:08:23.922Z","avatar_url":"https://github.com/pf4j.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"PF4J - Update\n=====================\n[![Travis CI Build Status](https://travis-ci.org/pf4j/pf4j-update.png)](https://travis-ci.org/pf4j/pf4j-update)\n[![Maven Central](http://img.shields.io/maven-central/v/org.pf4j/pf4j-update.svg)](http://search.maven.org/#search|ga|1|pf4j-update)\n\nThe goal of this project is to supply an update mechanism for [PF4J](https://github.com/pf4j/pf4j).\nIt's an open source (Apache license) lightweight (around 15KB) extension for PF4J, with minimal dependencies (only pf4j and gson).\n\nComponents\n-------------------\n- **UpdateManager** allows you to inspect the repositories (local, remote) for updates, available (new) plugins. Also this class allows you to install available plugins, update or uninstall existing plugins.\n- **UpdateRepository** defines a local/remote repository (pluggable)\n- **PluginInfo** defines the plugin information for each repository's plugin\n- **PluginRelease** defines a plugin release\n- **FileDownloader** defines a pluggable way of downloading from a repository\n- **FileVerifier** defines a pluggable way of verifying downloaded files, e.g. checksum verification\n\nUsing Maven\n-------------------\nIn your pom.xml you must define the dependencies to PF4J artifacts with:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.pf4j\u003c/groupId\u003e\n    \u003cartifactId\u003epf4j-update\u003c/artifactId\u003e\n    \u003cversion\u003e${pf4j-update.version}\u003c/version\u003e\n\u003c/dependency\u003e    \n```\n\nwhere ${pf4j-update.version} is the last pf4j-update version.\n\nYou may want to check for the latest released version using [Maven Search](http://search.maven.org/#search%7Cga%7C1%7Cpf4j-update)\n\nHow to use\n-------------------\nIt's very simple to add pf4j-update in your application.\nThe whole code of below snippet is available on [Github](https://github.com/pf4j/pf4j-update/blob/master/src/test/java/org/pf4j/update/util/TestApplication.java). \n\n```java\npublic static void main(String[] args) {\n    ...\n    \n    // create plugin manager\n    PluginManager pluginManager = new DefaultPluginManager();\n    pluginManager.loadPlugins();\n\n    // create update manager\n    UpdateManager updateManager = new UpdateManager(pluginManager);\n\n    // \u003e\u003e keep system up-to-date \u003c\u003c\n    boolean systemUpToDate = true;\n\n    // check for updates\n    if (updateManager.hasUpdates()) {\n        List\u003cPluginInfo\u003e updates = updateManager.getUpdates();\n        log.debug(\"Found {} updates\", updates.size());\n        for (PluginInfo plugin : updates) {\n            log.debug(\"Found update for plugin '{}'\", plugin.id);\n            PluginInfo.PluginRelease lastRelease = updateManager.getLastPluginRelease(plugin.id);\n            String lastVersion = lastRelease.version;\n            String installedVersion = pluginManager.getPlugin(plugin.id).getDescriptor().getVersion();\n            log.debug(\"Update plugin '{}' from version {} to version {}\", plugin.id, installedVersion, lastVersion);\n            boolean updated = updateManager.updatePlugin(plugin.id, lastVersion);\n            if (updated) {\n                log.debug(\"Updated plugin '{}'\", plugin.id);\n            } else {\n                log.error(\"Cannot update plugin '{}'\", plugin.id);\n                systemUpToDate = false;\n            }\n        }\n    } else {\n        log.debug(\"No updates found\");\n    }\n\n    // check for available (new) plugins\n    if (updateManager.hasAvailablePlugins()) {\n        List\u003cPluginInfo\u003e availablePlugins = updateManager.getAvailablePlugins();\n        log.debug(\"Found {} available plugins\", availablePlugins.size());\n        for (PluginInfo plugin : availablePlugins) {\n            log.debug(\"Found available plugin '{}'\", plugin.id);\n            PluginInfo.PluginRelease lastRelease = updateManager.getLastPluginRelease(plugin.id);\n            String lastVersion = lastRelease.version;\n            log.debug(\"Install plugin '{}' with version {}\", plugin.id, lastVersion);\n            boolean installed = updateManager.installPlugin(plugin.id, lastVersion);\n            if (installed) {\n                log.debug(\"Installed plugin '{}'\", plugin.id);\n            } else {\n                log.error(\"Cannot install plugin '{}'\", plugin.id);\n                systemUpToDate = false;\n            }\n        }\n    } else {\n        log.debug(\"No available plugins found\");\n    }\n\n    if (systemUpToDate) {\n        log.debug(\"System up-to-date\");\n    }\n\n    ...\n}\n```    \n\nThe library has very few components. The main component is the **UpdateManager**.  \nThis class contains methods for repositories inspection\n```java\npublic List\u003cUpdateRepository.PluginInfo\u003e getAvailablePlugins();\npublic boolean hasAvailablePlugins();\npublic List\u003cUpdateRepository.PluginInfo\u003e getUpdates();\npublic boolean hasUpdates();\npublic List\u003cUpdateRepository.PluginInfo\u003e getPlugins();\npublic List\u003cUpdateRepository\u003e getRepositories();\n```\nand methods for plugin handling\n```java\npublic boolean installPlugin(String url);\npublic boolean updatePlugin(String id, String url);\npublic boolean uninstallPlugin(String id);\n```\n\nUpdateManager can work with multiple repositories (local and remote).\nAll repositories are either defined in a `repositories.json` file or\nprovided in UpdateManager's constructor.\n\nBelow I defined two repository: localhost and folder.\n```json\n[\n  {\n    \"id\": \"localhost\",\n    \"url\": \"http://localhost:8081/\"\n  },\n  {\n    \"id\": \"folder\",\n    \"url\": \"file:/home/decebal/work/pf4j-update/downloads/\"\n  }  \n]\n```\n\nEach repository has a unique id and a URL.\n\nIn the root of this project you have a `repositories.json` file used by\nthe test applications.\n\nFor more information please see the test sources (UpdateTest, ...).\nIt's a good idea to run these tests and to see the results.\n\nCustomization\n-------------\nThe project is made for customization and extension to your own needs. Here are some\nexamples:\n\n### Tailor repository loading\nFirst you can supply to `UpdateManager` your custom location and name\nof `repositories.json` if you want it to live somewhere else.\n\nIf you need even more control, `UpdateManager` accepts repositories in\nconstructor and through setters.\nImplement your own `UpdateRepository`, `FileDownloader` and `FileVerifier`s\nto handle your own custom repsitory structures, authentication, checksum\nverifications etc.\n\n### Subclass UpdateManager\nFor full control, subclass `UpdateManager` and override relevant methods.\n\nRepository structure\n-------------------\nEach repository exposes multiple plugins using a `plugins.json` file.  \nBelow I registered two plugins: _welcome-plugin_ and _hello-plugin_.\n\n```json\n[\n  {\n    \"id\": \"welcome-plugin\",\n    \"description\": \"Welcome plugin\",\n    \"releases\": [\n      {\n        \"version\": \"0.8.0\",\n        \"date\": \"Jun 5, 2014 9:00:35 PM\",\n        \"url\": \"pf4j-demo-plugin1/0.8.0/pf4j-demo-plugin1-0.8.0.zip\"\n      },    \n      {\n        \"version\": \"0.9.0\",\n        \"date\": \"Jun 25, 2014 9:58:35 PM\",\n        \"url\": \"pf4j-demo-plugin1/0.9.0/pf4j-demo-plugin1-0.9.0.zip\"\n      }\n    ]\n  },\n  {\n    \"id\": \"hello-plugin\",\n    \"description\": \"Hello plugin\",\n    \"releases\": [\n      {\n        \"version\": \"0.8.0\",\n        \"date\": \"Jun 5, 2014 9:12:35 PM\",\n        \"url\": \"pf4j-demo-plugin2/0.8.0/pf4j-demo-plugin2-0.8.0.zip\"\n      },\n      {\n        \"version\": \"0.9.0\",\n        \"date\": \"Jun 25, 2014 9:58:35 PM\",\n        \"url\": \"pf4j-demo-plugin2/0.9.0/pf4j-demo-plugin2-0.9.0.zip\"\n      }\n    ]\n  }\n]\n```\n\n### plugins.json\n**Fields per plugin**\n\n|Property    |Format       |Description                        |\n|------------|-------------|-----------------------------------|\n|id          |string       |Unique id, mandatory               |\n|name        |string       |Display name (short)               |\n|description |string       |Describe your plugin               |\n|provider    |string       |Name of plugin provider            |\n|releases    |List         |List of releases (minimum one)     |\n\n**Fields per release**\n\n|Property    |Format       |Description                        |\n|------------|-------------|-----------------------------------|\n|version     |X.Y.Z        |Version of release ([SemVer](http://semver.org/) format) |\n|date        |date         |Release date, ISO8601 or `yyyy-MM-dd` format |\n|requires    |Expression   |[SemVer expression](https://github.com/zafarkhaja/jsemver#semver-expressions-api-ranges), e.g. \"\u003e=2.0.0\"  |\n|url         |URL-string   |Link to zip, either absolute or relative URL |\n|sha512sum   |\u0026lt;sha512-digest\u0026gt;\u003cbr/\u003e*or* \u0026lt;hash-file URL\u0026gt;\u003cbr/\u003e*or* \".sha512\" |String with SHA-512 HEX digest of file content\u003cbr/\u003eURL to file with SHA-512 string\u003cbr/\u003eFetch SHA-512 file next to plugin, with `.sha512` file suffix  |\n\n\n*New properties may appear in the future.*\n\nThe last (current) release of the plugin is calculated taking into account\nby the _version_ property. In our example, the last release for each\nplugin is the release with version _0.9.0_.\n\nWe encourage using `yyyy-MM-dd` format for release date. Localized US format\nas in the examples above will also work. If the date is not parsable, it\nwill be set to epoch (1970-01-01) and print a warning in logs.\n\n**NOTE**: The `requires` property was a simple X.Y.Z string in versions\nup to 0.3.0, interpreted as `\u003e=X.Y.Z`. You may want to update your old\n`plugins.json` files to the new syntax.\n\n### Example for 'hello-plugin' (plugin2):\nURL from `repositories.json`: `http://localhost:8081/`\nRelative URL in `plugins.json`: `pf4j-demo-plugin2/0.8.0/pf4j-demo-plugin2-0.8.0.zip`\nResulting `UpdateRepository.PluginRelease.url`: `http://localhost:8081/pf4j-demo-plugin2/0.8.0/pf4j-demo-plugin2-0.8.0.zip`\n\nIn the _downloads_ folder of the project you have a repository (plugins.json and artifacts - plugins archives) used by the test applications.\nThe structure of the repository is:\n\n- plugin1\n    - 0.8.0  \n        - plugin1.zip  \n    - 0.9.0  \n        - plugin1.zip  \n- plugin2  \n    - 0.8.0  \n        - plugin2.zip  \n    - 0.9.0        \n        - plugin2.zip  \n- plugins.json\n\nFor each plugin you have a folder (plugin1, plugin2) that contains subfolder for each version (0.8.0, 0.9.0). \nIn each version folder you have the plugin archive (.zip) according to PF4J specification.  \n\nMailing list\n--------------\nMuch of the conversation between developers and users is managed through [mailing list](http://groups.google.com/group/pf4j).\n\nVersioning\n------------\nThis project will be maintained under the Semantic Versioning guidelines as much as possible.\n\nReleases will be numbered with the follow format:\n\n`\u003cmajor\u003e.\u003cminor\u003e.\u003cpatch\u003e`\n\nAnd constructed with the following guidelines:\n\n* Breaking backward compatibility bumps the major\n* New additions without breaking backward compatibility bumps the minor\n* Bug fixes and misc changes bump the patch\n\nFor more information on SemVer, please visit http://semver.org/.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpf4j%2Fpf4j-update","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpf4j%2Fpf4j-update","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpf4j%2Fpf4j-update/lists"}