{"id":13741158,"url":"https://github.com/pschichtel/JavaCAN","last_synced_at":"2025-05-08T21:32:36.122Z","repository":{"id":42470414,"uuid":"143218625","full_name":"pschichtel/JavaCAN","owner":"pschichtel","description":"A simple JNI wrapper for the socketcan API provided by the Linux kernel. As it is wrapping a Linux Kernel API, it is intended for use on Linux only.","archived":false,"fork":false,"pushed_at":"2025-04-13T23:54:53.000Z","size":1488,"stargazers_count":57,"open_issues_count":6,"forks_count":21,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-14T00:36:52.448Z","etag":null,"topics":["can","isotp","java","jni","linux","socketcan"],"latest_commit_sha":null,"homepage":"https://schich.tel","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pschichtel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"pschichtel"}},"created_at":"2018-08-01T23:34:21.000Z","updated_at":"2025-04-13T23:54:57.000Z","dependencies_parsed_at":"2023-12-01T21:29:28.888Z","dependency_job_id":"b937d25c-a327-47d6-b86d-04b3b48349bd","html_url":"https://github.com/pschichtel/JavaCAN","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pschichtel%2FJavaCAN","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pschichtel%2FJavaCAN/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pschichtel%2FJavaCAN/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pschichtel%2FJavaCAN/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pschichtel","download_url":"https://codeload.github.com/pschichtel/JavaCAN/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253153163,"owners_count":21862318,"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":["can","isotp","java","jni","linux","socketcan"],"created_at":"2024-08-03T04:00:56.139Z","updated_at":"2025-05-08T21:32:35.662Z","avatar_url":"https://github.com/pschichtel.png","language":"Java","readme":"# JavaCAN [![Maven Central](https://img.shields.io/maven-central/v/tel.schich/javacan-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22tel.schich%22%20AND%20a:%22javacan-core%22)\n\nThis README is for the latest, possibly unreleased, version. For the documentation on the 2.x releases, check the `releases/2.x` branch.\n\nBindings for SocketCAN's CAN_RAW, CAN_BCM and CAN_ISOTP sockets with full support for blocking and non-blocking IO. Non-blocking IO is possible using the epoll module, that provides an API very\nsimilar to Java's Selector API.\n\nImplementing Java's SelectableChannel API is not possible with EPoll and SocketCAN due to various hardcoded assumptions in the JDK.\n\n## Is this project actively maintained?\n\nYes! While feature development tends to happen in bursts around specific topics, issues and pull requests will always be answered. Dependencies will be updated occasionally. Releases are made mostly based on demand. The master branch is generally in a releasable state, if you need something released, just ask for it.\n\n## What works?\n\n* Creating and binding CAN_RAW, CAN_BCM, CAN_ISOTP and CAN_J1939 sockets\n* Sending and receiving standard CAN and CAN-FD frames with and without EFF\n* Getting and setting all supported socket options\n* Event-driven networking using an [IOSelector](https://github.com/pschichtel/JavaCAN/blob/master/epoll/src/main/java/tel/schich/javacan/select/IOSelector.java)\n* Fairly robust test coverage\n\n## What is missing?\n\n* Support for other CAN protocols (e.g. CAN_MCNET)\n* [CAN XL](https://www.bosch-semiconductors.com/media/ip_modules/pdf_2/can_xl_1/canxl_intro_20210225.pdf)\n* A [netty](https://netty.io) integration (see [#20](https://github.com/pschichtel/JavaCAN/issues/20))\n* BSD Support\n* io_uring Support\n\nPull requests are welcome!\n\n## Related Projects\n\n* [obd4s](https://github.com/pschichtel/obd4s): A Scala library for OBD-II communication with vehicles.\n* [VirtualECU](https://github.com/pschichtel/VirtualECU): An ECU simulator to test OBD-II clients against.\n* [Apache PLC4X](https://plc4x.apache.org/users/transports/socketcan.html): Apache PLC4X brings support for various PLC systems. JavaCAN serves as the transport layer for [CANopen](https://plc4x.apache.org/users/protocols/canopen.html) and other CAN related protocols.\n\n## Supported Operating Systems\n\nThis project is a wrapper around SocketCAN, which is a Linux kernel module that implements CAN communication. As such, only Linux can be supported. For this reason, the custom Selector will also only\nuse epoll (Linux API for event-driven IO), as support for other OS' is not possible anyway.\n\n## Supported Architectures\n\nThe project uses [dockcross](https://github.com/dockcross/dockcross) to cross-compile its native components for various Linux supported platforms.\n\nCurrently, the full build process includes the following architectures:\n\n* `x86_32`\n* `x86_64`\n* `armv6`\n* `armv7`\n* `armv7a`\n* `armv7l` (musl libc, linked statically)\n* `aarch64`\n* `riscv32`\n* `riscv64`\n\nThe implementation can handle word sizes up to 64 bit and is byte order aware. If you need another architecture, feel free to ask for it! Alternatively read how to build another architecture\ndown below.\n\n### Android\n\nAdditionally, the following architectures are included specifically for Android:\n\n* `android-arm`\n* `android-arm64`\n* `android-x86_64`\n* `android-x86_32`\n\n## How to use\n\n### CAN_RAW, CAN_BCM and CAN_ISOTP channels\n\n1. Compile yourself or get a compiled release from Maven Central: [Core](https://central.sonatype.com/artifact/tel.schich/javacan-core), [EPoll](https://central.sonatype.com/artifact/tel.schich/javacan-epoll) (Check Versions -\u003e Browse for published artifacts)\n2. Install the native components into your `LD_LIBRARY_PATH` or configure the appropriate Java properties (See next section)\n3. Create a channel by calling one of the `CanChannels.new...Channel()` methods\n4. Create a `NetworkDevice` using its static `lookup(String)` method\n5. Bind the channel to an interface using the `bind(CanDevice)` method\n\nUsage example can be found in the unit tests or in the related projects mentioned above.\n\n**Remember**: JavaCAN is a fairly thin wrapper around Linux syscalls. Even though some aspects of the low-level C API are hidden, most Java APIs in this library will at some point call into a\n(usually similarly named) C API and as such inherits all of its properties. For example `RawCanChannel.close()` translates to a call to `close()` on the underlying file descriptor, so their behaviour\nshould be identical. So if the behaviour of a certain API is unclear, a look into the man pages of related Linux syscalls might help. Feel free to still request additional documentation in the issues\non [GitHub](https://github.com/pschichtel/JavaCAN)!\n\n#### Native components\n\nThe library relies on several native (JNI) components. By default, these components are either loaded from the standard library path (`LD_LIBRARY_PATH` / `java.library.path`) or are extracted from\nthe classpath into a temporary folder.  \n\nThere are a few approaches to get the correct native libraries loaded:\n\n1. Installing the libraries into the library path (the `LD_LIBRARY_PATH` environment variable or the `java.library.path` property)\n2. Configuring the `javacan.native.javacan-\u003cmodule\u003e.path` property to tell JavaCAN the exact file system path where the native component is located\n3. Configuring the `javacan.native.javacan-\u003cmodule\u003e.classpath` property to tell JavaCAN the exact location on the classpath where the native component is located\n4. Adding **one** of the architecture-specific jar files into the classpath (either at compile time or runtime)\n\nFor applications that are intended to run on a single architecture or that build architecture-specific versions already, the simplest solution is to bundle the provided architecture-specific jar files\nmatching the build architecture.\n\nFor applications supporting multiple architectures at once I'd recommend dynamically adding the architecture-specific jar file at runtime or to repackage the available native libraries and\ndynamically configuring the `javacan.native.javacan-\u003cmodule\u003e.path` properties in the CLI or before any JavaCAN classes are loaded. \n\nThe value for the `\u003cmodule\u003e` placeholder used throughout this section is `core` and if the EPoll support is used, an additional option with `epoll` for `\u003cmodule\u003e` is necessary.\n\n##### Architecture Detection\n\nWhile JavaCAN 2.x bundled the native components in its main artifacts, starting with the 3.x release series the native components are instead provided as\nseparate jar files (classified by their architecture). This provides full control over which library is loaded, especially on architectures on which the JVM doesn't provide enough\ninformation for a reliable architecture detection. Programs using JavaCAN usually depend on specific architectures and thus can pull just the relevant components and nothing more.\n\nFor applications like test tools that don't really care about program size and don't need to support every possible architecture, starting with JavaCAN 3.3 `*-arch-detect` modules are provided.\nThese modules bundle all prebuilt architectures and provide a function to automatically load the correct variant based on the `os.arch` system property.\n\nFor example for the `javacan-core` module you would instead depend on the `javacan-core-arch-detect` module and then, somewhere early in your program, invoke `JavaCANAutoDetect.initialize()`.\nThis will configure the necessary system property based on the architecture detection and eagerly initialize JavaCAN. \n\n## Troubleshooting\n\nIn case you have issues, have a look at the [troubleshooting document](TROUBLESHOOTING.md).\n\n## How to build\n\n### Prerequisites\n\nFor local compilation:\n\n* GCC (or compatible)\n* Java \u003e= 11\n\nFor cross compilation:\n\n* Podman or docker and permissions to run containers\n* Java \u003e= 11\n\nFor tests:\n\n* A fairly recent Linux kernel with CAN support\n* The can-isotp kernel module loaded (Kernel 5.10 with `CONFIG_CAN_ISOTP` enabled or the [out-of-tree module](https://github.com/hartkopp/can-isotp))\n* [can-utils](https://github.com/linux-can/can-utils) installed in the `PATH`\n* A CAN interface named \"vcan0\"\n* Java \u003e= 11\n\nFor usage:\n\n* A fairly recent Linux kernel with CAN support\n* For ISOTP channels, the can-isotp kernel module loaded (Kernel 5.10 with `CONFIG_CAN_ISOTP` enabled or the [out-of-tree module](https://github.com/hartkopp/can-isotp))\n* Java \u003e= 8\n* A few kilobytes of disk space to extract the native components\n\n\n### Building\n\nAll architectures can be built in parallel with using the `compileNativeAll` task:\n\n```bash\n./gradlew compileNativeAll\n```\n\nAlternatively there exist `packageNativeFor*` tasks for all the bundled architectures. A special task is packageNativeForHost, which will use\nthe compiler toolchain on your machine instead of dockcross. This is primarily intended for unit tests, but can also be used to build on systems\nthat are not supported by dockcross.\n\nAll architectures allow their dockcross image to be overridden by properties like `dockcross.image.\u003carchitecture\u003e`. The linking\nmode (`dynamic` or `static`) can also be overridden by properties like `dockcross.link.\u003carchitecture\u003e`.\n\nUsing the property `javacan.extra-archs` additional architectures can be defined as a comma-separated list. The values will be used as the\njar classifier. These additional architectures will also require manually setting configuring the dockcross image and linking mode using the\npreviously mentioned properties.\n","funding_links":["https://github.com/sponsors/pschichtel"],"categories":["Utils"],"sub_categories":["Libraries"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpschichtel%2FJavaCAN","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpschichtel%2FJavaCAN","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpschichtel%2FJavaCAN/lists"}