AI 资讯
Nine puzzle solvers, one browser tab, zero servers: a tour of classic search algorithms
I recently finished building a small suite of puzzle and game solvers that all run entirely in the browser — no backend, no API calls, no machine-learning models. You paste in a Sudoku, a chess position, or a crossword pattern, and the answer comes back instantly, computed on your own device. The fun part wasn't the UI. It was that each puzzle turned out to be a textbook excuse to reach for a different classic algorithm. Nine solvers, and I got to use constraint propagation, adversarial search, heuristic search, brute-force scanning, and plain old pattern matching — the stuff that shows up in an algorithms course and then, in most day jobs, never again. This is a tour of which algorithm fits which puzzle, and a few of the potholes I hit along the way. Everything here is vanilla JavaScript running in a Web Worker. The one design constraint: no server Before the algorithms, the rule that shaped all of them: it has to run client-side. That's a privacy choice (your puzzle never leaves the tab) and a cost choice (no compute bill), but it's also a fun forcing function. You can't lean on a beefy backend or a hosted model — you get one browser thread (well, a Worker thread) and whatever you can compute in a few hundred milliseconds. That budget is exactly why classic algorithms shine here. They're fast, deterministic, and small enough to ship as a script. Let's group the solvers by the technique each one leans on. Family 1: Constraint propagation Sudoku Sudoku is the poster child for constraint propagation. A cell that can only be one value forces that value; that in turn shrinks its neighbours' options, which forces more cells, and so on. Most "easy" and "medium" boards fall over from propagation alone (naked singles + hidden singles), and only the hard ones need a backtracking search on top. The nice property: the same engine that solves the board also powers the hint feature (find the next forced cell and explain why it's forced) and a uniqueness check — count solutions,
AI 资讯
Building a Client-Side Byte to String Decoder with Unicode Support
Hey DEV community! 👋 When debugging network streams, parsing custom file formats, or inspecting database buffers, we often extract data as raw arrays of numbers rather than human-readable text. This data typically presents itself as raw byte sequences formatted in either decimal or hexadecimal notation. While there are online decoders available, pasting raw byte sequences into third-party sites that process data on their backend databases introduces an unnecessary data privacy risk. To solve this, I designed a lightweight, entirely browser-based Byte to String Converter that decodes raw byte sequences locally using standard JavaScript APIs. In this post, we will look at how bytes map to character encodings and implement a client-side JavaScript utility to decode them safely. The Structure of a Byte In modern computing, a byte is the basic unit of digital information, consisting of an 8-bit sequence: 1 byte = 8 bits Because each bit represents a binary state (0 or 1), a single byte can represent: 2 8 = 256 states This translates to numeric values spanning from: Decimal (Base 10): Range of [ 0 , 255 ] Hexadecimal (Base 16): Range of [ 00 , FF ] When we render characters on a screen, we rely on character encoding tables (such as ASCII or UTF-8) to map these numerical byte values back to their original symbolic representations. Navigating Encodings: ASCII vs. UTF-8 The reconstruction process depends entirely on the encoding format used: ASCII: A basic 7-bit standard where each character maps to exactly one byte. It covers basic English letters, numbers, and core control characters. For example, the decimal value 72 maps to the uppercase letter 'H' . UTF-8: A variable-length encoding format that utilizes between 1 and 4 bytes per character. This structure allows UTF-8 to represent emojis, mathematical notations, and diverse language scripts. Our browser utility parses byte sequences using UTF-8 to maintain compatibility with modern web standards. JavaScript Implementatio
AI 资讯
I Built an API Because My Government’s Website Got the Date Wrong (and Just… Deleted It)
There’s a funny (and slightly sad) story behind why I built mabims.dev . It started with a date. More specifically, a Hijri date . Once Upon a Time, the Government Website Had the Date For a long time, Indonesia’s Ministry of Religious Affairs (Kemenag) website displayed the current Hijri date. It was convenient. You opened the website, looked at the corner of the page, and there it was: Today: 30 Sha'ban Simple enough. A lot of people, including me, got used to relying on it. Then one day, something weird happened. A post went viral. Someone noticed that the official calendar published by Kemenag said one date , while the date displayed on Kemenag’s own website said the next day . They were off by one day. People started asking: How can the official website and the official calendar disagree with each other? The post spread. People discussed it. And then… The Solution? Just Delete It. I didn't know what exactly happened behind the scenes. Maybe it was a bug. Maybe it was a calculation issue. Maybe the website was using a different data source. I don't know. But I do remember what happened eventually. The Hijri date disappeared from the website. Problem solved. Technically. If you can't display the wrong date, you can't display a wrong date. Elegant. 😂 At the time, I just thought it was funny. A few years later, I became a developer. And suddenly, the story made a lot more sense. Years Later, I Became a Junior Developer Once I started working as a developer, I learned how easy it is to add a Hijri date to a website. You don't need to calculate the lunar calendar yourself. You just install a library. Or call an API. There are plenty of them. The problem is that most of the libraries and APIs you'll find use Umm al-Qura by default. And that's perfectly reasonable. Umm al-Qura is the official calendar of Saudi Arabia. It's well documented, widely supported, and easy to integrate. For a developer who just wants: Gregorian date → Hijri date it works great. But there's a
AI 资讯
How a WhatsApp Web Extension Interacts With the Chat Interface
When people see a browser extension add translation controls, a side panel, or a sending workflow to WhatsApp Web, a common question is: how does the extension actually interact with the page? The short answer is that a modern Chrome extension is split across several execution environments. No single script should be responsible for the interface, persistent state, task scheduling, and access to the page at the same time. This article explains the architecture at a practical level without depending on private implementation details that may change whenever WhatsApp Web changes. A browser extension does not run as one program The simplest mental model is to divide the extension into four parts: The extension interface A background service worker A content script attached to WhatsApp Web A small bridge running in the page's own JavaScript context Each part has a different job and a different level of access. The extension interface is what the user sees: forms, task history, translation settings, saved scripts, and media selection. It should focus on interaction rather than long-running work. The background service worker coordinates tasks and stores state. It can receive a request from the interface, keep track of progress, and send commands to the correct WhatsApp Web tab. The content script lives alongside the webpage. It can inspect the rendered document, inject controls, and communicate with the extension runtime. Chrome isolates it from the page's own JavaScript environment for security. The page bridge exists because isolation is sometimes a limitation. A content script can see the DOM, but it does not automatically share the same JavaScript objects as WhatsApp Web. When deeper page integration is required, a carefully scoped bridge can exchange explicit messages between the isolated extension world and the page world. Why not put everything in the content script? It is tempting to keep the entire feature in one file because the content script is already attach
AI 资讯
OWASP Mobile Top 10 — M5: Insecure Communication
Welcome to the fifth article in our OWASP Mobile Top 10 2024 series! In previous articles we covered M1: Improper Credential Usage, M2: Inadequate Supply Chain Security, M3: Insecure Authentication/Authorization, and M4: Insufficient Input/Output Validation. Today we discuss why "we already use HTTPS" isn't a sufficient answer. Introduction M5 is the most misleading item on the list, because most teams read it and move on: "We use HTTPS, this doesn't apply to us." OWASP's definition is far broader. This risk covers all aspects of getting data from point A to point B, but doing it insecurely. It encompasses mobile-to-mobile communications, app-to-server communications, or mobile-to-something-else communications. It includes all communications technologies that a mobile device might use: TCP/IP, WiFi, Bluetooth/Bluetooth-LE, NFC, audio, infrared, GSM, 3G, SMS, etc. So M5 isn't just "do you use HTTPS." It's all of this: Whether you set up TLS correctly (certificate checking, cipher selection) Whether your traffic is consistent (some endpoints HTTPS, others not) What your third-party SDKs are doing What your WebView is loading What you send over alternate channels like push notifications and SMS 💡 Key point: Just because an app uses transport security protocols doesn't mean it's implemented correctly. HTTPS is not a checkbox; it's a system that must be configured properly. A specific situation for React Native developers In React Native the network layer lives in three separate places, and most developers only think about the first: The JavaScript side — fetch , axios , XMLHttpRequest Platform configuration — ATS on iOS, Network Security Config on Android Native modules and SDKs — analytics, ads, crash reporting, payment SDKs Whatever you do on the JavaScript side, if platform configuration is loose or a third-party SDK uses plaintext HTTP, your app is exposed. OWASP Assessment Metric Value Meaning Exploitability EASY A proxy and the same network is enough Prevalence CO
AI 资讯
🌱 Spring Boot Learning Series — Episode 2 | Spring Core
Episode 2 | Spring Core | Understanding IoC, Dependency Injection & Beans In Episode 1, I covered the WHY behind Spring — tight coupling, and how Spring takes over creating and providing objects (IoC + DI) instead of classes creating their own dependencies. This episode picks up from there with the parts I hadn't covered yet: how Spring actually does that under the hood — Beans, the Spring Container, and Component Scanning. 🔑 Keywords → 🧠 Understand → 💡 Why? → 💻 Practice → 🎯 Interview Questions → 🛠️ Project 🔑 Keywords for This Episode IoC & Dependency Injection (quick recap) Spring Bean Spring Container / ApplicationContext Component Scanning 1️⃣ Quick Recap: IoC & Dependency Injection From Episode 1: instead of a class creating its own dependency — public class TicketService { private TicketRepository repository ; public TicketService () { repository = new TicketRepository (); } } — Spring creates the dependency and hands it to the class. That's Inversion of Control (IoC) . In code, this usually looks like a constructor parameter: public class TicketService { private final TicketRepository repository ; public TicketService ( TicketRepository repository ) { this . repository = repository ; } } TicketService no longer says "let me create a TicketRepository." It says "I need a TicketRepository" — and Spring supplies one. That act of supplying it is Dependency Injection (DI) . IoC = who's in control of creating/managing objects → Spring. DI = how a class actually receives what it needs → passed in, not self-created. That's the recap. Now — where do these objects Spring creates actually come from, and where do they live? 2️⃣ Spring Bean — what Spring actually manages When Spring creates and manages an object for you, that object is called a Bean . This is the vocabulary you'll see everywhere in Spring code and docs, so it's worth being precise about it. @Service public class TicketService { } The @Service annotation is a signal to Spring: "this class should be managed b
开发者
I Built a Small API Gateway With Real Production Problems — On Purpose
Most gateway tutorials stop at "here's how you route a request." That's the easy 20%. The hard part is what happens when a client hammers you with requests, a downstream service falls over mid-traffic, or you're staring at a 500 trying to figure out which of your four services actually caused it. I wanted to build something that hits those problems on purpose, so I put together spring-gateway-sample : a public gateway , an api-server that fans out to two downstream services, and a full observability stack sitting behind all of it. It's not a real product and never will be. But I tried to make it behave like one — including the annoying bits, like config tradeoffs and races that most demos just quietly ignore. Stack, for context: Spring Boot 4.1, Spring Cloud Gateway on WebFlux, Resilience4j, Redis, Postgres, Keycloak, Prometheus/Grafana/Tempo/Loki, and a small Vue 3 app for throwing traffic at it from a browser. The system, in one request Browser (Vue traffic simulator) │ Keycloak PKCE login + API key ▼ Gateway ── JWT + API-key auth, Redis rate limiting ──▶ routes to │ ▼ api-server ── WebClient delegation, circuit breakers, Caffeine cache ──▶ │ │ ▼ ▼ product-service pricing-service (JPA / Postgres) (JPA / Postgres) Every hop re-validates the JWT on its own — defense in depth, so the gateway isn't the single thing standing between the internet and the data. The gateway also checks an API key on top, because a JWT tells you who the user is, not which client application is calling on their behalf. You need that second identity if you want per-client rate limits or the ability to revoke one app's access without touching anyone else's. Two checks, one specific order Every request needs a Keycloak JWT and an API key, and the order they're checked in isn't an accident: Missing or expired JWT → 401 , before the API key is even looked at. Valid JWT, bad API key → 401 , but a different error code. Both valid, wrong role → 403 . Why bother with the ordering? Because "you're no
产品设计
Article: Post-Quantum Cryptography in Spring Boot: Four Patterns You Can Ship This Sprint
There are four patterns that bring PQC into a Spring Boot fleet: encrypting payloads between services, locking down database fields, signing documents that need to hold up for decades, and moving service tokens off RS256. Along the way, we discuss why Harvest Now, Decrypt Later is already happening, and why none of this is production-safe until KMS or Vault is in place. By Pankaj Sharma
开发者
Audio Fingerprinting Discovered on Alibaba Websites While Debugging BLE Multipoint Disconnects
A recent discovery revealed that AliExpress employs silent audio streams for device fingerprinting, leveraging the Web Audio API. This technique involves analyzing hardware-specific audio processing to distinguish user devices. Privacy-focused browsers have developed countermeasures, highlighting a security gap in current web standards regarding audio context initialization and user privacy. By Olimpiu Pop
AI 资讯
Making HTTP Fail on Purpose: Building a Small Chaos Library for Java - Flaky HTTP
I recently built and open-sourced Flaky HTTP , a small Java 11 library for deliberately making HTTP calls less reliable. That may sound like an unusual goal. Most of the time, we work hard to make HTTP calls reliable. We add retries, timeouts, circuit breakers, fallbacks, caches, and monitoring. But eventually we need to answer a more difficult question: How do we know any of that behavior actually works? The original idea was simple: wrap Java's standard HttpClient , add controlled latency or synthetic HTTP errors to selected requests, and leave the rest of the application unchanged. That simple idea led to a few interesting decisions around API design, asynchronous cancellation, response body handling, deterministic testing, and the boundary between application-level failure injection and real network chaos. This article goes beyond a launch announcement. I want to explain why I built the library, how it works internally, where it is useful, and where it is deliberately limited. TL;DR Flaky HTTP is a lightweight wrapper around Java 11's java.net.http.HttpClient . It can: add fixed or random latency; return synthetic HTTP errors with a configurable probability; target requests using a full-URI regular expression; handle synchronous and asynchronous calls; propagate cancellation for delayed asynchronous work; and run without runtime dependencies beyond Java 11. The Maven coordinate is com.tapadyuti:flaky-http:1.0.0 . The shortest useful test setup is a deterministic failure: FlakyConfig config = FlakyConfig . builder () . failureRate ( 1.0 ) . errorStatus ( 503 ) . build (); Every targeted call now returns an empty synthetic 503 response without reaching the network. Replace 1.0 with 0.0 and add LatencyStrategy.fixed(500) when the test should exercise slowness without an HTTP error. It is intended for integration tests, resilience tests, local development, and controlled demonstrations. It is not a replacement for a network proxy or a full chaos-engineering platform
AI 资讯
A test said the server started. I deleted the server. It still passed.
Here is a test from a real, well run Node project: test ( ' server starts ' , async ( t ) => { const app = build () await app . listen ({ port : 0 }) t . assert . ok ( true , ' server started ' ) }) It reads fine in review. It runs green. Now delete the body of build() so the server never comes up. The test is still green, because the only thing it asserts is true . In the same file two more of these caught the error in a catch and asserted true there too, so even the failure path was green. That is not a made up example. I found it in fastify at a pinned commit and opened a PR to fix it. More on that at the end. A whole class of tests cannot fail Once you start looking, the pattern turns up in a few shapes: A literal: assert.ok(true) , expect(1).toBe(1) , a snapshot of a constant. An assertion parked in a catch the happy path never reaches, so nothing is checked when the code works and nothing is checked when it breaks. A status list that accepts both outcomes: assert.ok([200, 500].includes(res.status)) . Each one runs, counts toward coverage and guards nothing. Coverage is the trap. The line executed, so the tool that counts executed lines is happy. Whether the line would go red on a regression is a different question. It is the one that matters. Why review misses it A reviewer reading the diff sees a test called server starts , an await listen and a green tick. The name states intent. The assertion is what actually runs, yet ok(true) does not look like a problem until you stop and ask what would ever turn this test red. A missing check does not show up in a diff the way a wrong line does. Finding them I wrote a small scanner for this. No account, no config file, no network call: npx margyn-scan /path/to/repo One of its checks is cannot-fail : tests whose assertions hold whatever the code does. It also flags tests that assert nothing at all, files the build reads that git never committed, gates declared in package.json that no workflow invokes and linter exclusion
AI 资讯
I Built 143 Free Browser Tools — Then Added 144 Step-by-Step Guides for Every Single One
Last month I shared how I built 143 free online tools that run 100% in your browser — no signup, no uploads, no watermarks. That post got a great response (and a lot of "how is this free?" comments — answer: it stays free because files never touch a server, so there are no processing costs). Today's update: every single tool now has a full guide series. What's new 144 how-to articles — one per tool — live at toolfyra.vercel.app/blog : Step-by-step guides — every input explained, common pitfalls, pro tips Real competitor comparison tables (we scraped and analyzed who ranks for what, and where their tools annoy users with account walls) FAQ sections with schema markup so answers surface directly in search and AI assistants Unique generated illustrations per article Smart related-tools clusters — finish one task, the next tool is one click away Why guides for calculator tools? Because "how to use a calculator" is what people actually search for. Tools win clicks; guides win trust and rankings . Each article is built from real search-engine data: live SERP results, keyword expansions, and competitor FAQ analysis — zero guesswork. The engineering side (for the dev readers) Every tool is a single HTML page with vanilla JS — calculators run client-side, file tools use Canvas/FileReader APIs The blog is generated (Python build script): schema.org BlogPosting + FAQPage + BreadcrumbList, per-post OG images as optimized SVGs, canonical URLs, sitemap + IndexNow pings on every deploy New site-wide: instant search (type "pdf" → live results dropdown, keyboard-first: / to focus, ↑↓ to navigate), a Tools dropdown with 11 categories, and a mobile hamburger panel — all vanilla JS, no dependencies Privacy by architecture: there is literally no upload endpoint to breach What's next More waves of content (FAQ, mistakes-to-avoid, and comparison articles for every tool) A batch of new tools from our demand-research pipeline (we score thousands of real search phrases before writing a line
开源项目
🔥 bilawalsidhu / gods-eye-view - A spy satellite simulator in your browser, except the data i
GitHub热门项目 | A spy satellite simulator in your browser, except the data is real. Live open source spatial intelligence on a photorealistic 3D globe. | Stars: 7,705 | 1,984 stars today | 语言: JavaScript
AI 资讯
Building Cross-Framework Messaging with Quarkus, Micronaut, and RabbitMQ
The JVM ecosystem offers a wide range of powerful frameworks, each with its own strengths and capabilities. In a modern distributed architecture, however, applications are not always built using the same framework. Services developed with frameworks such as Quarkus, Micronaut, and Spring Boot may need to communicate seamlessly as part of the same system. This guide demonstrates how RabbitMQ can enable cross-framework asynchronous communication between JVM applications. We will build two applications using different frameworks: a Quarkus application that publishes LeaveRequest messages and a Micronaut application that consumes and processes them. The first application, built with Quarkus, publishes a LeaveRequest object as a message to RabbitMQ. The second application, built with Micronaut, receives the LeaveRequest message and processes it according to the application's business logic. By the end of this guide, you will have a practical understanding of how two applications built with different Java frameworks can communicate asynchronously using RabbitMQ. Lets begin the journey To ensure that both applications use a consistent message contract, create a separate Gradle project named common. This project will contain the shared LeaveRequest model and can be referenced as a dependency by both the Quarkus and Micronaut applications. @Introspected @Serdeable public record LeaveRequest ( String personName , String personRole , String facilityName , String wardName , String shiftName , String leaveReason , String recipientName , String recipientEmail , String recipient , String subject ) {} The dependency on the common project will be dependencies { annotationProcessor ( "io.micronaut:micronaut-inject-java:5.1.12" ) implementation ( "io.micronaut.serde:micronaut-serde-jackson:3.1.1" ) } The @Introspected and @Serdeable annotations enable Micronaut to generate the metadata required for efficient introspection and serialization. Connecting Quarkus to RabbitMQ To connect th
开发者
Spring News Roundup: First Milestone Releases for Boot, Framework, Data, Security, Modulith, Batch
After a 10-week hiatus since the last batch of Spring ecosystem releases, there was a flurry of activity during the week of August 17th, 2026, highlighting first milestone releases of: Spring Boot, Spring Framework, Spring Data, Spring Security, Spring Integration, Spring HATEOAS, Spring Modulith, Spring Batch, Spring AMQP and Spring for Apache Kafka. By Michael Redlich
开发者
Creating Web Widgets Using the Document Picture-in-Picture API
The general idea is that we create a Document Picture-in-Picture window (DPIP window), and then we put HTML, CSS, and JavaScript into it. Creating Web Widgets Using the Document Picture-in-Picture API originally handwritten and published with love on CSS-Tricks . You should really get the newsletter as well.
AI 资讯
Astro Introduces Sätteri: A Rust-powered Markdown And Mdx Processor With Up To 60% Faster Builds
Sätteri is a high-performance Markdown and MDX processor developed by the Astro team. Built in Rust, it enhances build speeds by up to 61% for Astro 7.0. Sätteri supports flexible JavaScript plugins and integrates various Markdown features natively. It maintains compatibility with the unified ecosystem while offering faster parsing and reduced dependencies. By Daniel Curtis
AI 资讯
Essential developer utility tools
1. Crypto & Security Tools Crucial for authentication setup, payload verification, and security testing. JWT Parser / Decoder: Decodes JSON Web Tokens ( Header , Payload , and Signature ) without transmitting secret keys over the internet. Token & Password Generator: Generates cryptographically secure random passwords and API tokens with customizable character sets, lengths, and complexity rules. Hash Text Generator: Computes cryptographic hashes (MD5, SHA-1, SHA-256, SHA-512) for strings to verify integrity or check signature matching. Bcrypt Hash / Verifier: Hashes plain-text passwords or checks plain text against an existing hash using the bcrypt algorithm. UUID / ULID Generator: Creates universally unique identifiers (v4 UUIDs) or time-sortable lexicographically sortable unique identifiers (ULIDs). BIP39 Mnemonic Generator: Generates seed phrases and cryptographic keys used in wallet initialization and HD key generation. RSA Key Pair Generator: Generates public and private RSA key pairs directly in the browser for local testing of asymmetric encryption systems. Basic Auth Generator: Quickly constructs Authorization: Basic <base64> HTTP header credentials from a username and password. 2. Formatters & Prettifiers (Development) Saves hours when dealing with messy logs, API responses, or raw system configurations. JSON Prettify & Minify: Formats unformatted API JSON strings with customizable indentation or compresses them into a single line to reduce payload sizes. JSON Diff: Highlights additions, deletions, and structural changes between two JSON payloads. SQL Prettify: Formats raw SQL queries into clean, readable multi-line statements with capitalized keywords. YAML / XML Formatter: Cleans up indentation, validates structure, and formats raw XML and YAML files. Docker Run to Docker Compose: Translates single CLI flags ( docker run -d -p 80:80 ... ) into a structured docker-compose.yml file. Cron Expression Generator & Parser: Provides human-readable schedules from
AI 资讯
A Self-Correcting Solar System Baseline From Sunrise/Sunset Data
A fixed-schedule solar baseline drifts out of sync with the sun throughout the year. In Phoenix the sun is up for 13 hours 10 minutes in late August and 10 hours 2 minutes at the December solstice. A flat daily kWh target flags that entire winter as a fault, then stays quiet on the July afternoon when one string dies at 2pm under full sun. The fix is to anchor the baseline to the actual sun instead of the clock, and most of what you need for that does not require an irradiance forecast. One thing before any code: sun geometry tells you when a system should be producing and when it should peak. It does not tell you how much light actually reached the panels. That is irradiance, and cloud cover swamps it. If you want modeled output in kWh, reach for Forecast.Solar or Solcast, which fold in weather and your array's tilt and azimuth. What follows is the free, dependency-light layer underneath that: the daylight window, the solar-noon peak, and the day-length trend. TL;DR Sun geometry (sunrise, sunset, solar noon, day length) catches a specific class of solar underperformance with no irradiance data. Gate alerts to the real daylight window so your monitor stops crying "underperformance" before sunrise. Track the daily production peak relative to solar noon. A persistent shift across comparable days can reveal shading, orientation, or system changes that a total-kWh check misses. Normalize a flat kWh target by day length so winter stops tripping false alarms. First-order fix, not a physics model. One call to an astronomy endpoint returns all of it. Code below in curl, Python, and Node. For real production forecasting, use an irradiance API. Sun times are the sanity layer, not the forecaster. Sun times will not predict your kWh, but they eliminate common timing-based false alarms and can surface useful production-shape anomalies early. Pull sunrise, sunset, solar noon, and day length once a day, gate your alerts to daylight, watch the peak, and scale the target for season.
AI 资讯
Java Service Steward, an open-source host for Java Windows services that reads wrapper.conf
Java Service Steward is a new Windows service host for Java applications. It reads the wrapper.conf format used by the Java Service Wrapper, follows the same command line and log format, and is licensed Apache-2.0 OR MIT. I wrote it because the Community Edition of the Java Service Wrapper has no 64-bit Windows build, and I did not want to buy a license or rewrite the service integration of applications that already had working configuration files. Repository: https://github.com/jayyanez/java-service-steward What it is The distribution is two files, wrapper.exe and wrapper.jar . The executable is written in Rust and does the Windows part: it registers the service, launches the JVM, keeps a control channel to it over a loopback socket, restarts it when it exits unexpectedly or stops answering pings, writes and rotates wrapper.log , and handles Service Control Manager requests (stop, pause, resume, custom control codes). The JAR is compiled for Java 8 and contains the launcher classes and a small API. There is no native DLL and no JNI. It only runs on 64-bit Windows. There is no Unix version. What is compatible Configuration. wrapper.conf with #include , #encoding , set.VAR=value , %VAR% expansion and numbered properties such as wrapper.java.additional.<n> . Relative paths resolve from the executable's directory, as before. Command line. -c runs in a console, -i and -r install and remove the service, -t and -p start and stop it, -q queries it, -d requests a thread dump. Property overrides on the command line and -- pass-through of application arguments work the same way. Service registration. An installed service's ImagePath calls wrapper.exe -s <conf> , so an existing registration keeps working. Log format. Records use the same LPTM layout, the same column widths and the same SIZE , WRAPPER and JVM roll modes, so scripts that parse wrapper.log do not need changes. Launchers. A configuration that names the original SimpleApp , StartStopApp or JarApp launcher in wrappe