Free & Open Source

Stop Restarting
SAP Commerce

Edit. Compile. Keep your JVM running. Explore supported Java and Spring changes, SAP Commerce workflows, and clear restart boundaries.

Built For SAP Commerce,
Not Adapted To It.

Reloading Java classes is the easy half. On SAP Commerce most of a day's edits are not Java at all: a type in items.xml, a property, a line of text in a locales file, an ImpEx. Reclazz reloads those too. Every item below was measured on a running 2211 server.

🧩

items.xml & beans.xml

Saving one runs the platform's own code generation and reloads the regenerated model and DTO classes, instead of ant clean all and a restart. A new attribute still needs its database column, so Reclazz tells you to run Update Running System rather than touching your schema itself.

🌱

Spring XML

Property edits in a *-spring.xml are applied to the live bean in place. A changed constructor argument, factory method or init/destroy method recreates that singleton through Spring itself and repairs the beans still holding the old one, and a brand new bean definition becomes available without a restart.

⚙

Properties

The platform reads its property files once, at startup. Save one now and the keys whose value actually changed are applied to the running server, through the same call the HAC console makes. Values consumed once at startup are named as still needing a restart, instead of being reported as done, and a key the platform refuses to write stays pending so that saving the same file again retries it.

📜

Log Levels

SAP Commerce keeps its levels in the property files rather than a log4j2.xml, as a name and level pair. Change one and it reaches the running logger, so turning a class up to debug costs a save instead of a restart. Levels you did not touch are left where they are, including one you raised from the HAC console.

🌐

Type & Enum Text

Edit a locales file and the new text is served on the next read. No system update, no database write, no restart.

🏷

Backoffice Labels

Label files reach the label cache backoffice actually reads from, every copy of it. Reopen the view and your text is there.

🔒

Interceptors

Validate, Prepare, Load, Remove and InitDefaults interceptors re-register: the mapping is captured before Spring refreshes the bean and put back into the platform registry afterwards, verified by a real model save that runs the new rule exactly once. A registration that fails says so instead of claiming success.

📤

ImpEx On Save

Changed .impex files can be imported the moment you save them. It is opt-in, because it runs against your live database, and a file carrying a REMOVE header, written out or hidden behind a macro, is named and refused rather than executed. A header macro the guard cannot resolve is refused the same way.

📁

Extension Aware

It reads your extension layout, classpath and classloader hierarchy on its own. There is no per-extension descriptor to write and keep in sync.

Reclazz vs JRebel on Hybris

JRebel reloads Java classes on SAP Commerce, and it does that well. The rest of what a hybris day is made of is a different question, and the honest place to answer it is JRebel's own SAP Commerce manual.

What you changed Reclazz JRebel
PriceFree & open source$550+/year per seat
A Java class✓✓
Per-extension setup fileNonerebel.xml for backoffice extensions
A type in items.xml or beans.xml✓ regenerates & reloads✗ not in its Hybris manual
A log level✓ applied to the running server✗ not in its Hybris manual
A property✓ applied to the running server✗ not in its Hybris manual
A type or enum name in a locales file✓✗ not in its Hybris manual
A backoffice label✓✗ not in its Hybris manual
An interceptor✓ re-registered✗ not in its Hybris manual
An ImpEx file✓ opt-in, imported on save✗ not in its Hybris manual
Licence server & activationNone, nothing leaves your machineCommercial licence, activation required

Compared against JRebel's own SAP Commerce manual, which covers reloading compiled classes and configuring rebel.xml. A cross means that capability is not described there, not that JRebel is broken: it reloads classes on Hybris and that is what it documents.

Deep Spring Integration.
Not Just Hot-Swap.

Reclazz understands Spring internals. When a class reloads, beans refresh, mappings re-scan, caches evict and schedulers re-register, and a method you add after startup is found by the framework that was going to look for it.

🌱

Spring Bean Refresh

Automatically destroys and recreates singleton beans after class reload. Your changes take effect immediately without losing application state.

🔌

MVC Re-scan

Re-registers @RequestMapping methods when a controller changes. An endpoint you add is served on the next request, on an ordinary JDK and inside a Tomcat webapp as well, instead of after a restart. An @ExceptionHandler, @InitBinder or @ModelAttribute you add to a running controller or advice runs through Spring's own selection, local priority and advice ordering included.

🔥

Cache Eviction

Evicts Spring caches for classes with @Cacheable, @CacheEvict, or @CachePut. No stale data after reload.

⏲

Scheduler Reload

Cancels and re-registers @Scheduled tasks. Changed cron expressions and fixed-rate schedules apply immediately, and a @Scheduled method you add after startup is registered on a stock JDK; removing it, or its annotation, cancels it.

🛠

Structural Changes

Add or remove methods and instance fields, and change annotations, on supported JDK 17+ paths. No patched JVM required. An added static field gets its initial value too, without re-running the rest of the static block. An enum value added on the end is applied to the running JVM, JDK 26 included: what that release closes is sun.misc.Unsafe, and the JDK's own Unsafe does the same writes. A changed compile-time constant is named together with the files that inlined it, and rebuilt where Reclazz is the compiler.

📄

Template Reload

Editing a Thymeleaf or Freemarker template takes effect on the next render, with caching left on.

⚙

Property & Log Changes

Spring Boot reads a properties file once, at startup. Save a .properties or .yml file now and it is reloaded at its own place in the Environment, so command-line overrides keep winning, a nested YAML value or list reaches the same binding as at startup, and a key you delete falls back to the next source or the default instead of staying stale. The @ConfigurationProperties beans that read it are rebound or, when constructor-bound, rebuilt and re-pointed; @Value fields are re-resolved, computed expressions included. Log levels, and a saved logback.xml or log4j2.xml, reach the running logging context too. An invalid value holds the whole save and says why.

🔍

It Explains Itself

When nothing happens, ask why: the build did not reach the class, it is built somewhere Reclazz does not watch, the bytes came out identical, or the JVM has not loaded it yet. None of those produce an error, which is why the log was empty. A second question, what still needs a restart, lists what this session left behind, and says so plainly when there is nothing.

🛡

AOP & Events

Clears AOP proxy caches for @Aspect classes and parses an edited pointcut again, instead of leaving every proxy matching the old expression. The one half a restart is still needed for is named: a bean already proxied keeps the advice it was built with until it is itself reloaded. Re-registers @EventListener methods, including ones you add after startup, and a @TransactionalEventListener you add fires at its transaction phase through Spring's own synchronization. Refreshes @Async processing.

📚

Spring Data & Security

Refreshes Repository beans. An edited @EnableWebSecurity configuration is rebuilt into the running filter chain, and method security (@PreAuthorize, @Secured) is re-read on the service class that carries it, not only on the security configuration. A @PreAuthorize or @PostAuthorize you add to a running service method, direct or a fixed composed marker, is enforced on both the classic Spring 5 and modern Spring 6 stacks.

🔄

What The Frameworks Cached

A reload is only half the job. Every framework answers from what it worked out about your class once, at startup, and nothing tells it otherwise. So an @Autowired you add to an existing field actually injects, a constraint you add is enforced on the next request, an @ExceptionHandler, @InitBinder or @ModelAttribute you add runs, an edited @Aspect pointcut is parsed again, and Jackson stops serialising the shape it first saw: a getter, a setter or a field you add to a DTO is written and read by the next request's JSON. Each one was measured on a running server, before and after.

🔧

Methods You Add Are Found

On a stock JDK a method you add lives on a hidden companion class, where a framework's scan cannot see it. Reclazz hands the framework the saved metadata instead: a new @Bean factory registers its product, with collections, Optional, providers and @Value arguments resolved by Spring; a new @PostConstruct or @PreDestroy runs on the next instance and keeps its destroy callback; a new @Transactional, @Cacheable, @Async or @PreAuthorize/@PostAuthorize service method runs through the real interceptors, custom composed forms and both the Spring 5 and Spring 6 security stacks included; an added @KafkaListener or @RabbitListener topic, group or queue can be a #{SpEL} expression and a @JmsListener can reply through @SendTo; an added @Bean factory honours a direct @Conditional or the Boot @ConditionalOnProperty, @ConditionalOnBean and @ConditionalOnMissingBean. A shape without an adapter is named as needing a restart, never silently skipped.

📬

Message Listeners

A @KafkaListener, @JmsListener or @RabbitListener you add to a running component registers through the application's own listener processor and container factory. Before the bean is recreated its existing consumers are stopped and waited for, so a queue is never consumed twice; edits, topic or queue changes, removal and restoration follow later saves. Verified against embedded Kafka and ActiveMQ brokers and a real RabbitMQ container.

⚡

Instant Hot-Swap

Redefines classes in the running JVM via the Instrumentation API. Method body changes apply in ~50ms. Zero downtime.

🔒

100% Local & Private

No telemetry, no analytics, no license server, no outbound requests. Everything runs on your machine. Your code never leaves your environment. The download carries its licence terms and a list of everything inside the agent, for whoever reviews it on your behalf.

Reclazz vs DevTools vs JRebel

Spring Boot DevTools restarts your entire context. JRebel costs $550+/year. Reclazz is free, open-source, and performs true in-place hot-swap.

Feature Reclazz Spring Boot DevTools JRebel
PriceFree & open sourceFree$550+/year
Reload typeIn-place hot-swapFull context restartIn-place hot-swap
Application statePreservedLost on restartPreserved
Reload speed~50msSeconds~50ms
Method body changes✓✓ (restart)✓
Add/remove methods & instance fields✓ supported JDK 17+ paths✓ (restart)✓
Added static field gets its value✓ (constants & self-contained initialisers)✓ (restart)✗ (initialiser not re-run)
Add enum values (on the end)✓ add or remove at the end, JDK 17-25✓ (restart)✓
Add/remove an interface✓ JBR or DCEVM; stock JDK refuses and says so✓ (restart)✓
Change superclass✗ no JVM redefines it✓ (restart)✓ loads classes itself
Spring bean refresh✓✓ (restart)✓
New @Service / @Controller class✓ supported JDK 17+ paths, wired and mapped✓ (restart)✓
Spring Security rules✓ filter chain rebuilt live✓ (restart)✓ separate plugin
@Bean method added after startup✓ supported JDK 17+ paths; collections, Optional, providers and @Value arguments✓ (restart)not documented
Handler or callback method added after startup✓ @ExceptionHandler, @InitBinder, @ModelAttribute, @Scheduled, @EventListener, @TransactionalEventListener, @PostConstruct, @PreDestroy✓ (restart)not documented
Message listener added after startup✓ @KafkaListener, @JmsListener, @RabbitListener; the old consumer is stopped first✓ (restart)not documented
Jackson property added after startup✓ getter, setter or field on a running DTO✓ (restart)✓
Properties and YAML follow the saved file✓ removed keys fall back, constructor-bound beans rebuilt✓ (restart)✓
Spring XML constructor, factory and init/destroy edits✓ singleton recreated, holders repaired✓ (restart)not documented
Deleted members stop being visible✓ hidden from reflection✓ (restart)✓
MVC mapping re-scan✓✓ (restart)✓
Cache eviction✓✓ (restart)not documented
@Scheduled re-register✓✓ (restart)✓
@EventListener refresh✓✓ (restart)not documented
AOP proxy refresh✓✓ (restart)not documented
JPA mapping picks up a new field✓ opt-in (jpaRefresh=true), JBR/DCEVM with ddl-auto; otherwise named in the log✓ (restart)✓ column still yours to add
New @Entity class picks up a mapping✓ supported JDK 17+ paths, opt-in✓ (restart)✓
SAP Commerce supportPurpose-built✗Generic
Open source✓ Apache 2.0✓✗

The Reclazz column is what the test suite covers, on SAP Commerce 2211 and Spring Boot 2.7 and 3.3. The JRebel column is what JRebel's own documentation describes; where it describes nothing, this says so rather than guessing. JRebel reloads Java classes well, and a blank cell is a gap in its manual, not a claim that it fails.

Works With Your JDK

Reclazz auto-detects your JDK and configures the right flags. Structural changes work everywhere; JetBrains Runtime additionally makes new members visible to reflection.

Measured, not assumed: SAP Commerce 2211 (20 of 20 integration scenarios on a live server), Spring Boot 2.7 and 3.3, Java 17 and 21 plus JetBrains Runtime 25, IntelliJ IDEA 2023.3 through 2026.2.

Standard JDK

JDK 17 / 21 / 25, any vendor
  • Method body changes
  • Add & remove methods and fields
  • Spring bean refresh
  • MVC re-scan & cache eviction
  • Scheduler & event reload
  • Change annotations
  • Auto-configured --add-opens flags

JetBrains Runtime / DCEVM optional

JBR / DCEVM 17 / 21 / 25
  • Everything above, plus:
  • New members visible to reflection
  • Reflective caches see them without a restart
  • Auto-configured -XX:+AllowEnhancedClassRedefinition

How Reclazz Works

A lightweight Java agent runs inside your application JVM. It watches compiled classes and orchestrates Spring-aware reloading.

What Can't Be Hot-Reloaded

These are fundamental JVM and framework limitations that no tool can fully overcome.

Class Hierarchy Changes

Changing superclass or interfaces is a JVM limitation. No tool can work around this. It requires a restart.

Reflection on New Members (standard JDKs)

Adding and removing methods or fields works on supported JDK 17+ paths. On a standard JDK the new members live on a hidden companion class, so code that calls them directly sees them, but reflection on the original class does not. Spring MVC, @Bean factories, schedulers, event and transaction listeners, lifecycle callbacks, Jackson and the Kafka, JMS and RabbitMQ listener containers get the saved metadata through adapters; a framework without one, Hybris ModelService attribute dispatch for instance, still needs a restart and is named. JetBrains Runtime or DCEVM removes the caveat entirely.

Configuration Beyond a File Edit

A loaded properties or YAML file reloads at its own precedence, and supported XML edits recreate the bean. What still needs a restart: a new config location, profile or import, a bean definition removed from XML, a changed class, scope or parent, and XML definitions with nested beans or managed collections. Each is named when it happens.

Creators, Proxies and Custom Scans

A new @Component class is live, but some shapes stay outside: Jackson constructor and record creators for added properties, a listener or lifecycle callback added to a proxied bean, custom listener factories, Jakarta lifecycle annotations, and frameworks that read your classes through their own reflection. Reclazz refuses these with the reason rather than applying half of them.

Up and Running in 3 Steps

1

Add the Agent

Download the agent from the latest GitHub release and add the -javaagent flag to your JVM arguments, or install the IntelliJ plugin, which injects it for you.

-javaagent:/path/to/reclazz-agent.jar
2

Run Your App

Start your Spring Boot application normally. Reclazz auto-detects your project layout and begins watching.

mvn spring-boot:run
3

Build & Reload

Change your code, then compile. Reclazz hot-swaps the changes automatically. No restart needed.

mvn compile or gradle classes

Frequently Asked Questions

No. Reclazz uses the standard JVM Instrumentation API, the same mechanism used by debuggers and profilers. If a hot-swap fails (e.g., a structural change on standard OpenJDK), the original class remains loaded and your application continues running normally.
DevTools restarts the entire Spring application context on every change, which takes seconds and loses all application state. Reclazz performs true in-place class redefinition, so your state is preserved, and reloads complete in ~50ms. Reclazz also handles Spring-specific concerns like MVC re-scanning, cache eviction, and scheduler re-registration without a restart.
Yes. Reclazz auto-detects target/classes (Maven) or build/classes/java/main (Gradle) from the classpath. Just run mvn compile or gradle classes and Reclazz hot-swaps the changes automatically.
Reclazz reports the error in the tool window and via a notification. The original class stays loaded, so your application is never left in a broken state. Common causes: superclass or interface changes, which always require a restart.
No. Reclazz is 100% local. There is no telemetry, no analytics, no license server, and no outbound network requests. Everything runs entirely on your machine. Your code never leaves your environment.
Yes, and it is the reason Reclazz exists. Saving a *-items.xml or *-beans.xml runs the platform's own code generation in the background and hot-reloads the regenerated model and DTO classes, instead of ant clean all and a restart. New attributes still need a database column, so Reclazz reminds you to run HAC > Update Running System rather than touching your database itself. On top of that: property changes applied to the running server, log levels applied to the running Log4j2 context, type and enum text re-read from locales files, backoffice labels refreshed, interceptor reload (Validate, Prepare, Load, Remove), *-spring.xml reload, ImpEx auto-import and extension-aware class watching.
Not required. Structural changes (adding and removing methods and fields) work on supported JDK 17+ paths. JetBrains Runtime or DCEVM additionally makes those new members visible to reflection and to caches built at startup. Reclazz auto-detects which runtime you're using and configures itself accordingly.
Reclazz is one, and it is open source under Apache 2.0 with no licence server and no per-seat cost. It reloads Java classes, including added methods and instance fields, on supported stock JDK 17+ paths. On SAP Commerce it also covers what a Java-only reload does not: saving a *-items.xml or *-beans.xml regenerates and reloads the model and DTO classes, property changes reach the running server, log levels change without a restart, locales text and backoffice labels refresh, *-spring.xml is applied to the live context, and an endpoint you just wrote answers on the next request. Compared against JRebel's own SAP Commerce manual, which documents reloading compiled classes and configuring rebel.xml, those platform-specific parts are not in it.
Save the file with Reclazz running. It runs the platform's own code generation in the background and hot-reloads the regenerated model and DTO classes into the server that is already up, so the change is live in seconds instead of a full rebuild and restart. A new attribute still needs a database column, so Reclazz prints a reminder to run HAC > Platform > Update Running System; it will not run DDL against your database itself. Measured on a running SAP Commerce 2211 server.
On a stock JDK the method lives on a hidden companion class, which is exactly what a reflective scan cannot see, so Reclazz hands each framework the saved metadata through an adapter. A new endpoint, exception handler, binder or model attribute method is served on the next request; a new @Bean, @Scheduled, @EventListener, @TransactionalEventListener, @PostConstruct or @PreDestroy registers; a new @KafkaListener, @JmsListener or @RabbitListener consumes after the previous consumer has been stopped; a new Jackson getter, setter or field is read and written. Each is a real test against the framework, and a shape without an adapter is named as needing a restart.

Stop Wasting Time on
Application Restarts

Keep your development session moving with supported reloads. Read the documentation for setup, framework conditions and restart requirements.

Search guides, changes and limits. Your query stays in this browser.

↑ ↓ to select · Enter to open · Esc to close