{"id":41865285,"url":"https://github.com/tomitribe/sabot","last_synced_at":"2026-01-25T11:40:02.390Z","repository":{"id":33800739,"uuid":"37494609","full_name":"tomitribe/sabot","owner":"tomitribe","description":"Environment-aware CDI-based Configuration","archived":false,"fork":false,"pushed_at":"2015-12-22T00:09:50.000Z","size":43,"stargazers_count":6,"open_issues_count":7,"forks_count":6,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-11-07T02:00:48.795Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomitribe.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-06-15T22:24:28.000Z","updated_at":"2025-04-16T03:46:19.000Z","dependencies_parsed_at":"2022-09-12T17:10:29.793Z","dependency_job_id":null,"html_url":"https://github.com/tomitribe/sabot","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/tomitribe/sabot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomitribe%2Fsabot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomitribe%2Fsabot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomitribe%2Fsabot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomitribe%2Fsabot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomitribe","download_url":"https://codeload.github.com/tomitribe/sabot/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomitribe%2Fsabot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28752668,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T10:25:12.305Z","status":"ssl_error","status_checked_at":"2026-01-25T10:25:11.933Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2026-01-25T11:40:01.322Z","updated_at":"2026-01-25T11:40:02.381Z","avatar_url":"https://github.com/tomitribe.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"= Sabot\n:showtitle:\n\n\"`A sabot /ˈsæboʊ/ is a device used in a firearm or cannon to fire a projectile, such as a bullet, that is smaller than the bore diameter, or which must be held in a precise position.`\"\n\nSabot is an environment-aware CDI Extension used to fire configuration into your applications with extreme precision.\nIt also happens to be the name of the awesome CDI spec-lead, https://twitter.com/antoine_sd[Antoine Sabot-Durand],\nwho wrote the core code this small project is based upon.\n\nFuture revisions may be donated or merged in with http://tamaya.incubator.apache.org/[Apache Tamaya].\n\nJava EE 6 or higher required.  Optional dependency on Apache TomEE 1.0 or higher.\n\n== @Inject @Config\n\nThe core concept is configuration data can be injected into your applications via `@Inject` with a simple `@Config` qualifier that names a property whose value you require.\n\nThe Properties themselves can come from `java.lang.System.getProperties()` using -D[property name]=[property value] on the command line, properties added to a `WEB-INF/classes/base.properties` file or\n(optionally for TomEE users) in the `conf/system.properties` file of your server.\n\n[source,java]\n----\n@Inject\n@Config(value = \"greeting\")\nprivate String greeting;\n\n@Inject\n@Config(value = \"color\", defaultValue = \"orange\")\nprivate String color;\n\n@Inject\n@Config(value = \"base\", defaultValue = \"${user.dir}\")\nprivate File userDir;\n\n@Inject\n@Config(value = \"home\", defaultValue = \"${user.home}\")\nprivate File defaultFile;\n\n@Inject\n@Config(value = \"service.timeout\", defaultValue = \"2 hours and 54 minutes\")\nprivate Duration timeout;\n\n@Inject\n@Config(value = \"service.enabled\", defaultValue = \"false\")\nprivate Boolean enabled;\n\n@Inject\n@Config(value = \"tx.retry\")\nprivate Integer retry;\n[source]\n----\n\n== Custom Configuration\n\nThere are various ways of customizing the configuration for differing environments. You can:\n\n* Add a 'test.properties' file to your test resources to override values found in the 'base.properties' file.\n* Add additional property file names via the System property 'org.tomitribe.sabot.environment' (Constant ConfigurationResolver.ENVIRONMENT)\n** -Dorg.tomitribe.sabot.environment=prod,dev - Sabot would then load the 'prod.properties' and 'dev.properties' files in that order.\n* Create a configuration observer and add to to the classpath - You can use the TomEEConfiguration.java as your starting point.\n[source,java]\n----\n@Singleton\npublic class YourConfiguration implements ConfigurationObserver {\n\n    static {\n        //This must occur before anything is initialized\n        ConfigurationResolver.registerConfigurationObserver(new YourConfiguration());\n    }\n....\n@Override\n    public void mergeConfiguration(final Properties resolved) {\n        ....[merge or override the configuration]\n    }\n----\n\n== Custom Java Types\n\nSabot does *not* use `java.beans.PropertyEditor` implementations by default like other String-to-Java libraries do.\n\nAfter 20 years of Java's existence, it's safe to say two styles dominate converting a `String` into a Java object:\n\n * A *Constructor* that take a single String as an argument.  Examples:\n ** `java.io.File(String)`\n ** `java.lang.Integer(String)`\n ** `java.net.URL(String)`\n * A *static method* that returns an instance of the same class.  Examples:\n ** `java.util.regex.Pattern.compile(String)`\n ** `java.net.URI.create(String)`\n ** `java.util.concurrent.TimeUnit.valueOf(String)`\n\n\nUse either of these conventions and Sabot will have no problem instantiating your object with the user-supplied `String` from the command-line args.\n\nThis should cover *95%* of all cases, but in the event it does not, you can create a `java.beans.PropertyEditor` and register it with the JVM.\nUse your Google-fu to learn how to do that.\n\nThe order of precedence is as follows:\n\n 1. Constructor\n 2. Static method\n 3. `java.beans.PropertyEditor`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomitribe%2Fsabot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomitribe%2Fsabot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomitribe%2Fsabot/lists"}