{"id":15044825,"url":"https://github.com/vsilaev/tascalate-javaflow","last_synced_at":"2025-08-19T21:31:35.540Z","repository":{"id":48294215,"uuid":"46494818","full_name":"vsilaev/tascalate-javaflow","owner":"vsilaev","description":"Continuations / CoRoutines for Java 1.6 - 23, build tools, CDI support. This project is based on completely re-worked Apache Jakarta Commons JavaFlow library.","archived":false,"fork":false,"pushed_at":"2024-04-19T22:31:40.000Z","size":1875,"stargazers_count":83,"open_issues_count":2,"forks_count":9,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-12-06T11:41:46.427Z","etag":null,"topics":["bytecode-instrumentation","cdi","continuation","continuations","coroutine","coroutine-framework","coroutine-library","coroutines","instrumentation-agent","jakarta-commons-javaflow","java","java-11","java-8","java-9","java-agent","java-library","java11","java8","java9","javaflow-instrumentation"],"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/vsilaev.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":"2015-11-19T13:45:06.000Z","updated_at":"2024-08-08T12:16:40.000Z","dependencies_parsed_at":"2022-08-24T12:51:05.042Z","dependency_job_id":"eb23c4da-3bfc-430d-91c4-0239a8ad49d8","html_url":"https://github.com/vsilaev/tascalate-javaflow","commit_stats":{"total_commits":263,"total_committers":3,"mean_commits":87.66666666666667,"dds":"0.18250950570342206","last_synced_commit":"e6d900b28aac1b402363c21f1166212c8e94db10"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsilaev%2Ftascalate-javaflow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsilaev%2Ftascalate-javaflow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsilaev%2Ftascalate-javaflow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsilaev%2Ftascalate-javaflow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vsilaev","download_url":"https://codeload.github.com/vsilaev/tascalate-javaflow/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230367928,"owners_count":18215338,"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":["bytecode-instrumentation","cdi","continuation","continuations","coroutine","coroutine-framework","coroutine-library","coroutines","instrumentation-agent","jakarta-commons-javaflow","java","java-11","java-8","java-9","java-agent","java-library","java11","java8","java9","javaflow-instrumentation"],"created_at":"2024-09-24T20:51:05.975Z","updated_at":"2025-08-19T21:31:35.532Z","avatar_url":"https://github.com/vsilaev.png","language":"Java","funding_links":[],"categories":["并发编程"],"sub_categories":[],"readme":"[![Maven Central](https://img.shields.io/maven-central/v/net.tascalate.javaflow/net.tascalate.javaflow.parent.svg)](https://search.maven.org/artifact/net.tascalate.javaflow/net.tascalate.javaflow.parent/2.7.9/pom) [![GitHub release](https://img.shields.io/github/release/vsilaev/tascalate-javaflow.svg)](https://github.com/vsilaev/tascalate-javaflow/releases/tag/2.7.9) [![license](https://img.shields.io/github/license/vsilaev/tascalate-javaflow.svg)](http://www.apache.org/licenses/LICENSE-2.0.txt)\n\n# IMPORTANT NOTICE FOR RELEASE 2.7.0!!!\n- Agents \u0026 Tools projects were refactored to follow consisntent naming of classes and to avoid package name clashes\n- Separate provider was extracted from `CdiProxy` to allow reuse in mutliple scenarious (not only in Java Agent)\n- `net.tascalate.javaflow.provider.asm[VERSION]` artifacts are deprecated now and scheduled for removal in next release\n\n# IMPORTANT NOTICE FOR RELEASE 2.5.0!!!\nJava 9+ is fully supported now, all artefacts are modular multi-release JAR-s that works correctly with Java versions 1.6 to 25. The library code was tested with JDK 25, and all features of the Java 25 bytecode (including nest of inner classes, sealed classes, records) works correctly.\n\n# IMPORTANT NOTICE FOR RELEASE 2.3.0!!!\n- `net.tascalate.javaflow.extras` artifact is withdrawn, its code serves as a basis for the project [Tascalate JavaFlow Extras](https://github.com/vsilaev/tascalate-javaflow-extras)\n- All examples are moved to separate project [Tascalate JavaFlow Examples](https://github.com/vsilaev/tascalate-javaflow-examples)\n\n# Continuation support for Java\nThis project contains libary, tools and examples to develop Java applications using continuations. \n\nAccording to Wikipedia \"a continuation is an abstract representation of the control state of a computer program; a continuation reifies the program control state, i.e. the continuation is a data structure that represents the computational process at a given point in the process's execution; the created data structure can be accessed by the programming language, instead of being hidden in the runtime environment\"\n\nIn other words, continuation allows you to capture execution state of the program (local variables, execution stack, program counters etc.) at the certain places and later resume execution from the saved point. Unfortunately, Java has no support for first-class continuations, but it can be added via bytecode instrumentation (like this library did)\n\nThe project is based on the completely reworked Apache Jakarta-Commons JavaFlow project (http://commons.apache.org/sandbox/commons-javaflow/). Below is a list of major changes:\n\n1. Original JavaFlow instruments bytecode of each and every method available for tooling to add Continuations support. This adds significant overhead to both code size and execution time. The reworked version requires developer to mark Continuation-aware classes/methods explicitly with annotations.\n2. Code is updated to use new bytecode instrumentation tools (ObjectWeb ASM 5.x); support for BCEL is discontinued \n3. Codebase is split to separate modules: run-time API, instrumentation provider SPI, offline instrumentation tools (Maven, Ant, command-line), run-time instrumentation JavaAgent, utilities and examples\n4. The library adds support for recent Java features like lambdas and dynamic dispatch\n\n# Maven\n\nYou have to add the following configuration to enable build-time instrumentation of classes during Maven build:\n```xml\n\u003cdependencies\u003e\n\t\u003cdependency\u003e\n\t\t\u003cgroupId\u003enet.tascalate.javaflow\u003c/groupId\u003e\n\t\t\u003cartifactId\u003enet.tascalate.javaflow.api\u003c/artifactId\u003e\n\t\t\u003cversion\u003e2.7.9\u003c/version\u003e\n\t\u003c/dependency\u003e\n\t\u003c!-- Add-on for Java 8 and above --\u003e\n\t\u003cdependency\u003e\n\t\t\u003cgroupId\u003enet.tascalate.javaflow\u003c/groupId\u003e\n\t\t\u003cartifactId\u003enet.tascalate.javaflow.extras\u003c/artifactId\u003e\n\t\t\u003cversion\u003e2.4.5\u003c/version\u003e\n\t\u003c/dependency\u003e\t\n\t...\n\u003c/dependencies\u003e\n\n\u003cbuild\u003e\n\t\u003cplugins\u003e\n\t\t\u003cplugin\u003e\n\t\t\t\u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n\t\t\t\u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n\t\t\t\u003cconfiguration\u003e\n\t\t\t\t\u003c!-- versions 1.6 -- 25 are supported --\u003e\n\t\t\t\t\u003csource\u003e1.6\u003c/source\u003e\n\t\t\t\t\u003ctarget\u003e1.6\u003c/target\u003e\n\t\t\t\t\u003c!-- For JDK 21+ uncomment the following compiler settings (instead of source/target) ---\u003e   \n\t\t\t\t\u003c!-- --enable-preview is optional, but it allows to use more efficient ScopedValue instead \n                                     of ThreadLocal for continuations core\n\t\t\t\t\u003c!--\t                                 \n\t\t\t\t\u003crelease\u003e21\u003c/release\u003e  \n\t\t\t\t\u003ccompilerArgs\u003e\n\t\t\t\t\t\u003carg\u003e--enable-preview\u003c/arg\u003e\n\t\t\t\t\u003c/compilerArgs\u003e\n\t\t\t\t--\u003e\n\t\t\t\u003c/configuration\u003e\n\t\t\u003c/plugin\u003e\n\t\t\u003cplugin\u003e\n\t\t\t\u003cgroupId\u003enet.tascalate.javaflow\u003c/groupId\u003e\n\t\t\t\u003cartifactId\u003enet.tascalate.javaflow.tools.maven\u003c/artifactId\u003e\n\t\t\t\u003cversion\u003e2.7.9\u003c/version\u003e\n\t\t\t\u003cexecutions\u003e\n\t\t\t\t\u003cexecution\u003e\n\t\t\t\t\t\u003cid\u003ejavaflow-enhance-main-classes\u003c/id\u003e \n\t\t\t\t\t\u003cphase\u003eprocess-classes\u003c/phase\u003e\n\t\t\t\t\t\u003cgoals\u003e\n\t\t\t\t\t\t\u003cgoal\u003ejavaflow-enhance\u003c/goal\u003e\n\t\t\t\t\t\u003c/goals\u003e\n\t\t\t\t\u003c/execution\u003e\n\t\t\t\t\u003c!-- Only if you need to enhance test classes --\u003e\n\t\t\t\t\u003cexecution\u003e\n\t\t\t\t\t\u003cid\u003ejavaflow-enhance-test-classes\u003c/id\u003e \n\t\t\t\t\t\u003cphase\u003eprocess-test-classes\u003c/phase\u003e\n\t\t\t\t\t\u003cgoals\u003e\n\t\t\t\t\t\t\u003cgoal\u003ejavaflow-enhance\u003c/goal\u003e\n\t\t\t\t\t\u003c/goals\u003e\n\t\t\t\t\u003c/execution\u003e\t\t\t\t\n\t\t\t\u003c/executions\u003e\n\t\t\u003c/plugin\u003e\n\t\u003c/plugins\u003e\n\u003c/build\u003e\n```\nNote that if you are using continuations with Java 1.8 lambdas then you need to add [Tascalate JavaFlow instrumentation agent](https://github.com/vsilaev/tascalate-javaflow/releases/download/2.7.9/javaflow.instrument-continuations.jar) at run-time as command-line option, while lambda-related classes are generated by JVM on the fly and there is no other way to instrument them. If this is not an option, then you can de-sugar all lambdas with [RetroLambda](https://github.com/luontola/retrolambda) Maven plugin at build-time (RetroLambda output is supported by Tascalate JavaFlow 2.3.2 or higher).\n\nPlease refer to [pom.xml](https://github.com/vsilaev/tascalate-javaflow-examples/blob/master/net.tascalate.javaflow.examples.common/pom.xml) in examples project for typical Maven configuration.\n\n# Gradle\nTo use continuations bytecode enhancer with Gradle you need to do the following.\nFirst, specify JavaFlow gradle plugin dependency in `build.gradle`:\n```groovy\nbuildscript {\n    repositories {\n        mavenCentral()\n    }\n\n    dependencies {\n      classpath 'net.tascalate.javaflow:net.tascalate.javaflow.tools.gradle:2.7.9'\n    }\n}\n```\nNext, apply the `continuations` plugin and specify the dependency to the `net.tascalate.javaflow.api`:\n```groovy\napply plugin: \"java\"\napply plugin: \"continuations\"\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation 'net.tascalate.javaflow:net.tascalate.javaflow.api:2.7.9'\n}\n```\nWith JDK 21+ add the following configuration to use ScopedValue instead of ThreadLocal for continuation internals:\n```\ntasks.withType(JavaExec) {\n    jvmArgs += '--enable-preview'\n}\n```\n# Ant\n\nThere is a separate Ant task for applying JavaFlow instrumentation at build-time. \n\nIt's possibe to instrument compiled Java classes as below:\n```xml\n\u003ctarget name=\"instrument-classes\" description=\"JavaFlow Instrumentation\" depends=\"compile\"\u003e\n    \u003ctaskdef name=\"javaflow\" \n    classname=\"org.apache.commons.javaflow.tools.ant.ContinuableClassesInstrumentationTask\" \n    classpathref=\"ant-lib-classpath\"/\u003e\n    \u003cecho message=\"JavaFlow instrumentation of compiled classes in ${classes.dir}\" /\u003e\n    \u003cjavaflow srcdir=\"${classes.dir}\" destdir=\"${i-classes.dir}\" classpathref=\"classpath\"/\u003e\n\u003c/target\u003e\n```\n... as well as re-write packaged JAR file:\n```xml\n\u003ctarget name=\"instrument-jar\" description=\"JavaFlow Instrumentation\" depends=\"jar\"\u003e\n    \u003ctaskdef name=\"javaflow\" \n    classname=\"org.apache.commons.javaflow.tools.ant.ContinuableClassesInstrumentationTask\" \n    classpathref=\"ant-lib-classpath\"/\u003e\n    \u003cecho message=\"JavaFlow instrumentation of compiled classes in ${jar.dir}/${ant.project.name}.jar\" /\u003e\n    \u003cjavaflow srcdir=\"${jar.dir}\" destdir=\"${i-jar.dir}\" classpathref=\"classpath\"/\u003e\n\u003c/target\u003e\n```\nYou may download a complete [examples project setup](https://github.com/vsilaev/tascalate-javaflow-examples/releases/download/1.0.10/tascalate-javaflow-ant-project-setup1.zip) from [the latest release](https://github.com/vsilaev/tascalate-javaflow-examples/releases/tag/1.0.10) for complete configuration template. Please pay attention to \u003ccode\u003eant-lib\u003c/code\u003e folder with Ant TaskDef and \u003ccode\u003elib\u003c/code\u003e folders with compile-/runtime-dependencies.\n\n# Java Instrumentation Agent (Runt-time Instrumentation)\nAs an alternative to compile-time bytecode instrumentation, you MAY use [Tascalate JavaFlow Instrumentation Agent](https://github.com/vsilaev/tascalate-javaflow/releases/download/2.7.9/javaflow.instrument-continuations.jar) from [the latest release](https://github.com/vsilaev/tascalate-javaflow/releases/tag/2.7.9) to enable continuations support at class-loading time. Please note, that if you are using Java 8 and creating continuable lambda functions (either anonymous or/and as method references), and you don't replace them with tools like [RetroLambda](https://github.com/luontola/retrolambda) as mentioned above, then you SHOULD use this instrumentation agent always: as long as Java run-time generates implementation of functional interfaces on the fly there is no other option to instrument them. To enable Tascalate JavaFlow Instrumentation Agent please add the following arguments to Java command line:\n```bash\njava -javaagent:\u003cpath-to-jar\u003e/javaflow.instrument-continuations.jar \u003crest-of arguments\u003e\n```\nThe agent JAR file includes all necessary dependencies and requires no additional CLASSPATH settings. It's recommended to use this agent in conjunction with either Maven or Ant build tools supplied to minimize the associated overhead of the instrumentation during class-loading process at run-time.\n\nAnother useful application of the instrumentation agent is to apply it for debugging code within your IDE of choice. Just specify the \"-javaagent\" option listed above in your IDE debug/run configuration and you will be able to perform quick \"debug-fix\" loops without executing full project rebuild. \n\n# Command-line tools\nIt's possible to use a stand-alone command-line utility [JavaFlowRewriteJar.jar](https://github.com/vsilaev/tascalate-javaflow/releases/download/2.7.9/JavaFlowRewriteJar.jar) to instrument JAR archives containing continuable classes. Please use the following command:\n\n```bash\njava -jar JavaFlowRewriteJar.jar src1.jar dst1.jar src2.jar dst2.jar...\n```\nNote, that the source and the destination should be different files.\n\n# CDI Support\nTo work correctly in CDI environment continuable methods should be advised only by continuation-aware CDI proxies (interceptors, scope proxies, etc). Obviously, generation of these proxies is out of our control. Plus, major CDI containers (JBoss Weld and Apache OpenWebBeans) generates such proxies dynamically at run-time. Therefore if you plan to use Tascalate JavaFlow continuations with managed beans' methods then it's necessary to instrument CDI-specific proxies with [javaflow.instrument-proxies.jar](https://github.com/vsilaev/tascalate-javaflow/releases/download/2.7.9/javaflow.instrument-proxies.jar) Java Agent:\n```bash\njava -javaagent:\u003cpath-to-jar\u003e/javaflow.instrument-proxies.jar \u003crest-of arguments\u003e\n```\nPlease note, that CDI-specific agent neither requires javaflow.instrument-continuations.jar to operate correctly nor provides class file transformers for continuable methods. So if your project runs with CDI environment AND uses Java 8 lambdas then you have to add 2 Java agents, every serving different purpose:\n```bash\njava -javaagent:\u003cpath-to-jar\u003e/javaflow.instrument-continuations.jar \\\n     -javaagent:\u003cpath-to-jar\u003e/javaflow.instrument-proxies.jar \\\n     \u003crest-of arguments\u003e\n```\nCDI functionality is tested with JBoss Weld 2.x - 3.1.7, 4.0.x and Apache OpenWebBeans 1.6.x - 2.0.23. Contribution for other CDI/CDI-like containers (Spring, Google Guice, etc) is welcome.\n\n# More documentation \u0026 exmaples\nExamples of the library usage may be found in the [Tascalate JavaFlow Examples](https://github.com/vsilaev/tascalate-javaflow-examples) project. The covered topics are common tasks, inheritance, lambdas support, proxies, usage with CDI containers like JBoss Weld and Apache OpenWebBeans.\n\nFor additional documentation, tutorials and guidelines please visit my [blog](http://vsilaev.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvsilaev%2Ftascalate-javaflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvsilaev%2Ftascalate-javaflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvsilaev%2Ftascalate-javaflow/lists"}