GOSS is a JMS-based messaging framework providing client/server architecture, request/response patterns, and security integration for distributed power grid applications. It serves as the foundation for GridAPPS-D and other grid simulation platforms.
- ActiveMQ 6.2.0 with Jakarta JMS 3.1 (from javax.jms)
- Apache Shiro 2.0.0 (from 1.x)
- Jakarta EE APIs (from Java EE)
- Spring Framework 6.x, Jackson 2.18.x, SLF4J 2.0.x
See the JDK 21 Upgrade section below for details.
- OpenJDK 21 (or compatible JDK 21 distribution)
- Gradle 8.10+ (included via wrapper)
1. Clone the repository:
git clone https://github.com/GridOPTICS/GOSS.git
cd GOSS2. Build and run (choose one):
./gradlew :pnnl.goss.core.runner:createSimpleRunner
java -jar pnnl.goss.core.runner/generated/executable/goss-simple-runner.jar- Size: ~33 MB
- Type: Fat JAR with all dependencies
- Use case: Quick testing, development
./gradlew buildRunner.goss-core
java -jar pnnl.goss.core.runner/generated/runners/goss-core-runner.jar- Size: ~62 MB
- Type: Apache Felix OSGi framework with bundles
- Use case: Production, modular deployments
- Includes: Updated dependencies (ActiveMQ 6.2.0, Jakarta JMS, Shiro 2.0)
3. Verify GOSS is running:
Once started, you can use these Gogo shell commands:
gs:listDataSources - Lists registered datasources
gs:listHandlers - Lists registered request handlers
GOSS includes a BndRunnerPlugin that creates executable OSGi JARs from any .bndrun file.
For any .bndrun file in your project:
./gradlew buildRunner.<name>Examples:
./gradlew buildRunner.goss-core # Uses goss-core.bndrun
./gradlew buildRunner.my-app # Uses my-app.bndrunCreate a file like my-app.bndrun:
# OSGi Framework
-runfw: org.apache.felix.framework;version='[7.0.5,8)'
-runee: JavaSE-21
# Bundles to include
-runbundles: \
${activemq-runpath},\
${jakarta-runpath},\
${slf4j-runpath},\
pnnl.goss.core.core-api;version=latest,\
pnnl.goss.core.goss-client;version=latest,\
pnnl.goss.core.goss-core-server;version=latest
# Runtime properties
-runproperties: \
activemq.host=0.0.0.0,\
openwire.port=61616,\
stomp.port=61613Then build it:
./gradlew buildRunner.my-app
java -jar pnnl.goss.core.runner/generated/runners/my-app-runner.jarThe plugin is available in buildSrc/ and can be used in other projects:
1. Copy buildSrc to your project:
cp -r GOSS/buildSrc /path/to/your/project/2. Apply the plugin in your build.gradle:
apply plugin: com.pnnl.goss.gradle.BndRunnerPlugin
bndRunner {
bundleDirs = [
file('generated'),
file('../GOSS/pnnl.goss.core/generated') // Include GOSS bundles
]
configDir = file('conf')
}3. Use it:
cd /path/to/your/project
./gradlew buildRunner.my-runtimeThe Java client now supports both Queue and Topic destination types, matching the Python client's behavior:
import pnnl.goss.core.Client.DESTINATION_TYPE;
// Subscribe to a queue (point-to-point, for request/response patterns)
client.subscribe("goss.gridappsd.process.request", handler, DESTINATION_TYPE.QUEUE);
// Subscribe to a topic (pub/sub, for broadcast events)
client.subscribe("goss.gridappsd.simulation.output.123", handler, DESTINATION_TYPE.TOPIC);
// Publish to a queue
client.publish("goss.gridappsd.process.request", message, DESTINATION_TYPE.QUEUE);
// Publish to a topic
client.publish("goss.gridappsd.platform.log", message, DESTINATION_TYPE.TOPIC);
// Send request and get response (defaults to QUEUE to match Python)
client.getResponse(request, "goss.gridappsd.process.request", RESPONSE_FORMAT.JSON);
// Send request with explicit destination type
client.getResponse(request, "my.topic", RESPONSE_FORMAT.JSON, DESTINATION_TYPE.TOPIC);Key differences:
| Destination | Publishing Behavior | Subscribing Behavior |
|---|---|---|
| QUEUE | Message delivered to one consumer. If no consumers, message is stored until one connects. | Only one subscriber receives each message (load balancing). |
| TOPIC | Message delivered to all active subscribers. If no subscribers, message is lost. | All subscribers receive a copy of each message (broadcast). |
Default behaviors:
getResponse()defaults to QUEUE (matches Python client, ensures request reaches the handler)subscribe()defaults to TOPIC (typical for event streaming)publish(destination, message)defaults to TOPIC (for backward compatibility)
A new CLI tool for subscribing and publishing to GOSS queues/topics:
# Build the CLI
./gradlew :pnnl.goss.core.runner:createCli
# Subscribe to a queue
java -jar pnnl.goss.core.runner/generated/executable/goss-cli.jar subscribe --queue goss.gridappsd.process.request
# Subscribe to a topic
java -jar pnnl.goss.core.runner/generated/executable/goss-cli.jar sub --topic goss.gridappsd.simulation.output.123
# Publish to a queue (default)
java -jar pnnl.goss.core.runner/generated/executable/goss-cli.jar publish goss.gridappsd.process.request '{"type":"query"}'
# Publish to a topic
java -jar pnnl.goss.core.runner/generated/executable/goss-cli.jar pub --topic goss.gridappsd.platform.log 'Test message'
# With authentication and custom broker
java -jar pnnl.goss.core.runner/generated/executable/goss-cli.jar sub -b tcp://activemq:61616 -u admin -p admin -q my.queueOptions:
-t, --topic- Use a topic (default for subscribe)-q, --queue- Use a queue (default for publish)-b, --broker URL- Broker URL (default: tcp://localhost:61616)-u, --user USER- Username for authentication-p, --password PW- Password for authentication-h, --help- Show help message
# Terminal 1 - Start first subscriber
$ java -jar goss-cli.jar sub --topic events
GOSS Subscriber
===============
Broker: tcp://localhost:61616
Destination: events
Type: TOPIC
Connected! Waiting for messages... (Ctrl+C to stop)
# Terminal 2 - Start second subscriber
$ java -jar goss-cli.jar sub --topic events
Connected! Waiting for messages... (Ctrl+C to stop)
# Terminal 3 - Publish a message
$ java -jar goss-cli.jar pub --topic events "Hello everyone!"
Message published successfully!
# Result: BOTH Terminal 1 AND Terminal 2 receive:
--- Message Received ---
Hello everyone!
------------------------# Terminal 1 - Start first consumer
$ java -jar goss-cli.jar sub --queue tasks
GOSS Subscriber
===============
Broker: tcp://localhost:61616
Destination: tasks
Type: QUEUE
Connected! Waiting for messages... (Ctrl+C to stop)
# Terminal 2 - Start second consumer
$ java -jar goss-cli.jar sub --queue tasks
Connected! Waiting for messages... (Ctrl+C to stop)
# Terminal 3 - Publish messages
$ java -jar goss-cli.jar pub --queue tasks "Task 1"
$ java -jar goss-cli.jar pub --queue tasks "Task 2"
# Result: Terminal 1 receives "Task 1", Terminal 2 receives "Task 2" (load balanced)
# Each message goes to only ONE consumer
# Queue persistence - messages wait for consumers:
$ java -jar goss-cli.jar pub --queue waiting "I'll wait here"
# (no subscribers running - message is stored)
# Later, start a subscriber:
$ java -jar goss-cli.jar sub --queue waiting
--- Message Received ---
I'll wait here
------------------------
# Message was stored and delivered when consumer connected!GOSS uses Apache Shiro integrated with ActiveMQ via the ShiroPlugin. All broker connections (OpenWire, STOMP) require authentication and are subject to permission checks.
See the Security Guide for full details on user management, permissions, and token authentication.
Quick overview:
- Users are configured in
pnnl.goss.core.runner/conf/pnnl.goss.core.security.propertyfile.cfg - Permissions control access to queues, topics, and temporary queues
- JWT tokens allow clients to authenticate once and reconnect without re-sending credentials
Clients now automatically renew their JMS session when publish operations fail, improving reliability in long-running applications.
GOSS uses Semantic Versioning with automated API change detection:
| Change Type | Version Bump | Example |
|---|---|---|
| MAJOR | X.0.0 | Interface changes, removed public methods, breaking changes |
| MINOR | x.Y.0 | New public methods on classes, new classes (backward compatible) |
| PATCH | x.y.Z | Implementation-only changes, bug fixes |
make version # Show versions of all bundles
make build # Build all bundles
make test # Run tests
make clean # Clean build artifacts
make run # Build and run GOSS in the background (logs to log/goss.log)
make stop # Stop the background GOSS process
make status # Check if GOSS is running
make log # Tail the GOSS log file
make itest # Build, start GOSS, run integration tests, stop GOSSBefore bumping versions, analyze your changes to determine the appropriate version bump:
make check-api # Analyze API changes and get recommendationExample output:
API Change Analysis
============================================================
pnnl.goss.core.core-api
MAJOR changes detected:
- Interface method removed: public abstract void publish(javax.jms.Destination, ...)
- Interface method added: public abstract void publish(jakarta.jms.Destination, ...)
pnnl.goss.core.goss-client
MINOR changes detected:
- Public method added: public void reconnect()
pnnl.goss.core.goss-core-commands
No API changes
============================================================
Recommended Version Bump:
MAJOR - Breaking API changes detected
Run: make bump-major
# Automatic version bumping (reads current version, increments appropriately)
make bump-major # 11.0.0 -> 12.0.0-SNAPSHOT (breaking changes)
make bump-minor # 11.0.0 -> 11.1.0-SNAPSHOT (new features)
make bump-patch # 11.0.0 -> 11.0.1-SNAPSHOT (bug fixes)
make next-snapshot # Same as bump-patch (use after release)
# Manual version setting
make release VERSION=11.0.0 # Set exact release version (removes -SNAPSHOT)
make snapshot VERSION=11.1.0 # Set exact snapshot version (adds -SNAPSHOT)# 1. Analyze changes to determine version bump type
make check-api
# 2. If currently on snapshot, set release version
make version # Verify: 11.0.0-SNAPSHOT
make release VERSION=11.0.0 # Changes to: 11.0.0
# 3. Build, test, and push release
make build && make test
make push-release # Push to ../GOSS-Repository/release/
# 4. Tag and commit release
git add -A && git commit -m "Release 11.0.0"
git tag v11.0.0
git push && git push --tags
# 5. Start next development cycle
make next-snapshot # Bumps to: 11.0.1-SNAPSHOT
git add -A && git commit -m "Start 11.0.1-SNAPSHOT development"
git pushGOSS bundles can be published to a local GOSS-Repository clone for OSGi resolution:
# Push snapshot JARs to ../GOSS-Repository/snapshot/
make push-snapshot
# Push release JARs to ../GOSS-Repository/release/
make push-releaseNote: The GOSS-Repository must be cloned as a sibling directory (../GOSS-Repository). This is the local repository used for BND workspace resolution, not a remote Maven repository.
When making changes to GOSS, follow these guidelines:
MAJOR version bump required:
- Adding or removing methods from an interface (breaks implementors)
- Removing public methods from a class
- Changing method signatures (parameters, return types)
- Changing class hierarchy (superclass, implemented interfaces)
MINOR version bump required:
- Adding new public methods to a class (not interface)
- Adding new classes
- Adding new packages
PATCH version bump required:
- Bug fixes with no API changes
- Performance improvements
- Internal refactoring
- Documentation updates
- Quick Start Guide - Get up and running with GOSS in 5 minutes
- Developer Setup - Complete development environment setup for Eclipse and VS Code
- Production Deployment - Production deployment guide with systemd, SSL, and monitoring
- Security Guide - Authentication, permissions, JWT tokens, and user management
- Code Formatting Guide - Code style and formatting configuration for consistent code across IDEs
- Documentation Index - Complete documentation hub
- Issue Tracker - Report bugs or request features
Ubuntu/Debian:
sudo apt update
sudo apt install openjdk-21-jdk
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64CentOS/RHEL/Fedora:
sudo dnf install java-21-openjdk-devel # Fedora
sudo yum install java-21-openjdk-devel # CentOS/RHELmacOS (Homebrew):
brew install openjdk@21
export PATH="/usr/local/opt/openjdk@21/bin:$PATH"Windows: Download from Adoptium or OpenJDK
Using SDKMAN (recommended for development):
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk install java 21.0.5-tem
sdk use java 21.0.5-temBefore (Java EE):
import javax.jms.Connection;
import javax.annotation.PostConstruct;After (Jakarta EE):
import jakarta.jms.Connection;
import jakarta.annotation.PostConstruct;Updated packages:
jakarta.jms:jakarta.jms-api:3.1.0(wasjavax.jms)jakarta.annotation:jakarta.annotation-api:2.1.1jakarta.resource:jakarta.resource-api:2.1.0jakarta.transaction:jakarta.transaction-api:2.0.1jakarta.inject:jakarta.inject-api:2.0.1jakarta.xml.bind:jakarta.xml.bind-api:4.0.2
- ActiveMQ 6.2.0 (was 5.15.x)
- Native Jakarta JMS support
- No more shim/bridge layers
- Updated broker configuration
- Shiro 2.0.0 (was 1.x)
- API changes in authentication/authorization
- Updated security configuration
- Spring Framework 6.2.0 (was 5.x)
- Jackson 2.18.1 (was 2.17.x)
- SLF4J 2.0.16 (was 1.7.x)
- Apache Felix 7.0.5 OSGi framework
- Gradle 8.10 with BND 6.4.0
- Updated to OSGi R8 specifications
- Modular BndRunnerPlugin for creating custom OSGi runners
- Improved bundle dependency resolution
✅ Environment:
- Install JDK 21
- Set
JAVA_HOMEto JDK 21 - Verify:
java -versionshows 21.x
✅ Code Updates (if extending GOSS):
- Replace
javax.jms.*withjakarta.jms.* - Replace other
javax.*EE packages withjakarta.* - Update Shiro security configurations for 2.0 API changes
- Test ActiveMQ connections (configuration may need updates)
✅ Build:
- Update Gradle wrapper if using older version
- Clear Gradle cache:
./gradlew clean - Run tests:
./gradlew check
ActiveMQ Configuration:
- Old broker URLs still work, but new features require updated configuration
- SSL/TLS configuration has changed in ActiveMQ 6.x
Shiro Security:
- Some authentication realm APIs have changed
- Review custom
Realmimplementations
Removed Java EE APIs:
- All
javax.jms,javax.annotation, etc. → Use Jakarta equivalents
GOSS/
├── pnnl.goss.core/ # Core bundles
│ ├── core-api/ # Core API interfaces
│ ├── goss-client/ # Client implementation
│ ├── goss-core-server/ # Server implementation
│ ├── goss-core-server-api/ # Server API interfaces
│ ├── goss-core-security/ # Security integration (Shiro)
│ └── security-propertyfile/ # Property-file authentication
├── pnnl.goss.core.runner/ # Executable runners
│ ├── goss-core.bndrun # OSGi runtime definition
│ └── conf/ # Runtime configuration
├── buildSrc/ # Gradle plugins (BndRunnerPlugin)
├── cnf/ # BND workspace configuration
├── scripts/ # Build and release scripts
├── Makefile # Build automation
└── push-to-local-goss-repository.py # Repository publishing tool
GOSS serves as the messaging foundation for:
- GridAPPS-D - Grid Application Platform for Planning and Simulation with Distribution. GridAPPS-D is built as an OSGi application on top of GOSS, using its messaging framework for simulation orchestration, data management, and application integration.
- Java 21 with modern language features
- OSGi (Apache Felix 7.0.5) for modular service architecture
- BND Tools 6.4.0 for OSGi bundle management
- Apache ActiveMQ 6.2.0 for JMS messaging (Jakarta EE compatible)
- Apache Shiro 2.0 for authentication and authorization
- Gradle 8.10 build system
| Repository | Description |
|---|---|
| GOSS-GridAPPS-D | GridAPPS-D platform built on GOSS |
| GOSS-Repository | OSGi bundle repository for BND resolution |
| gridappsd-docker | Docker deployment for GridAPPS-D |
| gridappsd-python | Python client library |
This project is licensed under the BSD-2-Clause License. See LICENSE for details.
Contributions are welcome! Please submit pull requests to the develop branch.
- Documentation: See the docs/ directory
- Issues: https://github.com/GridOPTICS/GOSS/issues