{"id":16859518,"url":"https://github.com/raphw/wicket-async-task","last_synced_at":"2025-07-12T03:05:28.298Z","repository":{"id":9667288,"uuid":"11608080","full_name":"raphw/wicket-async-task","owner":"raphw","description":"This is a small extension to Wicket that allows the management of asynchronous tasks and to display their progress to the user.","archived":false,"fork":false,"pushed_at":"2016-11-28T09:40:18.000Z","size":304,"stargazers_count":10,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-11T08:35:27.759Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/raphw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-07-23T12:45:18.000Z","updated_at":"2019-07-28T18:18:42.000Z","dependencies_parsed_at":"2022-08-24T03:10:19.802Z","dependency_job_id":null,"html_url":"https://github.com/raphw/wicket-async-task","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/raphw/wicket-async-task","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphw%2Fwicket-async-task","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphw%2Fwicket-async-task/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphw%2Fwicket-async-task/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphw%2Fwicket-async-task/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/raphw","download_url":"https://codeload.github.com/raphw/wicket-async-task/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphw%2Fwicket-async-task/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264929170,"owners_count":23684777,"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":[],"created_at":"2024-10-13T14:18:08.438Z","updated_at":"2025-07-12T03:05:28.263Z","avatar_url":"https://github.com/raphw.png","language":"Java","readme":"This is a small extension to Wicket that allows the management of asynchronous tasks (starting, interrupting and restarting) and to display a task's progress and state to the user. In order to allow tasks to communicate their progress, they have to implement `IProgressObservableRunnable` which is provided in this package. \n\nAlso, tasks can be managed outside of the scope of a webpage without breaking Wicket's contract that all `Component`s must be `Serializable` by offering a `TaskManager` interface. A default implementation of such a task manager is provided.\n\nThe extension can be used like this:\n\n```java\npublic class DemoPage extends WebPage implements IRunnableFactory {\n\n    public DemoPage() {\n\n        Form\u003c?\u003e form = new Form\u003cVoid\u003e(\"form\");\n        AbstractTaskContainer taskContainer = DefaultTaskManager.getInstance()\n            .makeContainer(1000L, TimeUnit.MINUTES);\n        ProgressButton progressButton = new ProgressButton(\"button\", form, \n            Model.of(taskContainer), this, Duration.milliseconds(500L));\n        ProgressBar progressBar = new ProgressBar(\"bar\", progressButton);\n\n        add(form);\n        form.add(progressButton);\n        form.add(progressBar);\n    }\n\n    @Override\n    public Runnable getRunnable() {\n        return new MyRunnable();\n    }\n    \n    private static class MyRunnable implements IProgressObservableRunnable {\n        // Implementation of a Runnable with observable progress\n        ...\n    }\n}\n```\n\nA demo application is provided in *wicket-async-task-demo*. The actual implementation can be found *wicket-async-task-impl*.\n\n**Important note**: Do not implement `Runnable`s as non-static inner classes of a Wicket class. (This is rather common in Wicket, especially with concern to anonymous inner classes, so be careful.) These classes are expected to be detached and serialized by the Wicket framework. Therfore, do not attemt the following:\n\n```java\npublic class DemoPage extends WebPage implements IRunnableFactory {\n    \n    ...\n\n    @Override\n    public Runnable getRunnable() {\n        return new IProgressObservableRunnable() {\n            // This class keeps an implicit reference to its \n            // containing WebPage. The page might be in a \n            // detached state when the inner class tries to access it.\n            // Also, this will cause a memory leak to you application \n            // since this instance can not be garbage collected as \n            // long as this task did not expire.\n        }\n    }\n}\n```\n\nIn addition, do not attempt to call Wicket methods from the background task. If you for example want to transform exceptions in background threads into Wicket error messages, this would be what you want to do:\n\n```java\npublic class DemoPage extends WebPage implements IRunnableFactory {\n\n    public DemoPage() {\n\n        ...\n        \n        ProgressButton progressButton = new ProgressButton(\"button\", form, \n            Model.of(taskContainer), this, Duration.milliseconds(500L)) {\n            \n                @Override\n                protected void onTaskError(AjaxRequestTarget ajaxRequestTarget) {\n                    // This method is always executed from the GUI thread.\n                    // Therefore, it is safe to poll the possible exception\n                    // from the background thread.\n                    Throwable th = getTaskContainer().getExecutionError();\n                    if (th != null) {\n                        error(th.getLocalizedMessage()));\n                    }\n                }\n                \n        }\n    }\n    \n    ...\n}\n```\n\nAs long as you keep your background tasks free from references to your Wicket classes, you are safe. Be particularly careful with the following:\n* Using non-static implementations of *IModel*: models are often implemented as anonymous classes. Therefore, they carry a reference to the containing `Component`.\n* Using *@SpringBean* annotated variables: Those Spring beans are actually bound to the application and implemented as proxies. Instead, use `WebApplication.get().getServletContext()` in order to find the beans directly by `WebApplicationContextUtils.getWebApplicationContext(servletContext).getBean(MyBean.class)`\n\nLicensed under the Apache Software License, Version 2.0\n\n[![Build Status](https://travis-ci.org/raphw/wicket-async-task.png)](https://travis-ci.org/raphw/wicket-async-task)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraphw%2Fwicket-async-task","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fraphw%2Fwicket-async-task","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraphw%2Fwicket-async-task/lists"}