{"id":13753472,"url":"https://github.com/StubbornJava/StubbornJava","last_synced_at":"2025-05-09T21:34:55.283Z","repository":{"id":15225689,"uuid":"77759012","full_name":"StubbornJava/StubbornJava","owner":"StubbornJava","description":"Unconventional Java code for building web servers / services without a framework. Think dropwizard but as a seed project instead of a framework. If this project had a theme it would be break the rules but be mindful of your decisions.","archived":false,"fork":false,"pushed_at":"2023-01-20T05:06:48.000Z","size":1157,"stargazers_count":233,"open_issues_count":56,"forks_count":124,"subscribers_count":19,"default_branch":"master","last_synced_at":"2024-11-16T06:30:23.546Z","etag":null,"topics":["ansible","css-themes","dropwizard","dropwizard-metrics","gradle","hikaricp","jackson","java","java15","jool","jooq","json","logback","okhttp3","slf4j","terraform","undertow"],"latest_commit_sha":null,"homepage":"https://www.stubbornjava.com","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/StubbornJava.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-12-31T23:11:41.000Z","updated_at":"2024-10-04T04:34:19.000Z","dependencies_parsed_at":"2023-02-12T00:00:59.371Z","dependency_job_id":null,"html_url":"https://github.com/StubbornJava/StubbornJava","commit_stats":null,"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StubbornJava%2FStubbornJava","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StubbornJava%2FStubbornJava/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StubbornJava%2FStubbornJava/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StubbornJava%2FStubbornJava/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StubbornJava","download_url":"https://codeload.github.com/StubbornJava/StubbornJava/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253328874,"owners_count":21891542,"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":["ansible","css-themes","dropwizard","dropwizard-metrics","gradle","hikaricp","jackson","java","java15","jool","jooq","json","logback","okhttp3","slf4j","terraform","undertow"],"created_at":"2024-08-03T09:01:22.943Z","updated_at":"2025-05-09T21:34:54.843Z","avatar_url":"https://github.com/StubbornJava.png","language":"Java","readme":"[![Release](https://jitpack.io/v/StubbornJava/StubbornJava.svg)](https://jitpack.io/#StubbornJava/StubbornJava)\r\n[![Follow @StubbornJava](https://img.shields.io/twitter/follow/stubbornJava.svg?style=social)](https://twitter.com/intent/follow?screen_name=StubbornJava) \r\n\r\n\r\n\r\n# StubbornJava\r\nhttps://www.stubbornjava.com/\r\n\r\nThis is very much a work in progress and in the early stages. No code will be pushed to maven central or supported in any way currently. Feel free to clone and install locally. The website is built using all the methods described on the site and in the examples. There is no backing blog framework.\r\n\r\nPotentially moving to [GitLab](https://gitlab.com/stubbornjava/StubbornJava)\r\n\r\n## Quick Example (full example [Simple REST server in Undertow](https://www.stubbornjava.com/posts/lightweight-embedded-java-rest-server-without-a-framework))\r\n\r\n```java\r\npublic static void createUser(HttpServerExchange exchange) {\r\n    User userInput = userRequests.user(exchange);\r\n    User user = userDao.create(userInput.getEmail(), userInput.getRoles());\r\n    if (null == user) {\r\n        ApiHandlers.badRequest(exchange, String.format(\"User %s already exists.\", userInput.getEmail()));\r\n        return;\r\n    }\r\n    exchange.setStatusCode(StatusCodes.CREATED);\r\n    Exchange.body().sendJson(exchange, user);\r\n}\r\n\r\npublic static void getUser(HttpServerExchange exchange) {\r\n    String email = userRequests.email(exchange);\r\n    User user = userDao.get(email);\r\n    if (null == user) {\r\n        ApiHandlers.notFound(exchange, String.format(\"User %s not found.\", email));\r\n        return;\r\n    }\r\n    Exchange.body().sendJson(exchange, user);\r\n}\r\n    \r\npublic static final RoutingHandler ROUTES = new RoutingHandler()\r\n    .get(\"/users/{email}\", timed(\"getUser\", UserRoutes::getUser))\r\n    .post(\"/users\", timed(\"createUser\", UserRoutes::createUser))\r\n    .get(\"/metrics\", timed(\"metrics\", CustomHandlers::metrics))\r\n    .get(\"/health\", timed(\"health\", CustomHandlers::health))\r\n    .setFallbackHandler(timed(\"notFound\", RoutingHandlers::notFoundHandler));\r\n\r\npublic static final HttpHandler ROOT = CustomHandlers.exception(EXCEPTION_THROWER)\r\n    .addExceptionHandler(ApiException.class, ApiHandlers::handleApiException)\r\n    .addExceptionHandler(Throwable.class, ApiHandlers::serverError);\r\n\r\npublic static void main(String[] args) {\r\n    SimpleServer server = SimpleServer.simpleServer(Middleware.common(ROOT));\r\n    server.start();\r\n}\r\n```\r\n\r\n# Suggest a Topic\r\nCheck out [issues](https://github.com/StubbornJava/StubbornJava/issues) to suggest topics, bug fixes, errors, or vote on issues. Reactions / comments may influence the order topics are added but no guarantees. Several topics will not be accepted here such as larger frameworks (Spring, Play, Jersey ...) as well as dependency injection. We will be more focused on rolling things yourself and solving practical problems. The coding style here may not fit with the norm but it should be very easy to convert any of the classes to be DI friendly.\r\n\r\n# Getting Started\r\nA [guide for building your own minimal embedded Java web server](https://www.stubbornjava.com/guides/embedded-java-web-server). A simple in order intro to a lot of uses cases for simple web development.\r\n\r\n# Dev Tools\r\n* [Creating a local development environment with Docker Compose](https://www.stubbornjava.com/posts/creating-a-local-development-environment-with-docker-compose) (MySQL, Elasticsearch)\r\n* [Configuring servers with Ansible](https://www.stubbornjava.com/posts/installing-java-supervisord-and-other-service-dependencies-with-ansible)\r\n\r\n# HTML / CSS Themes and Templates for rapid prototyping\r\n* [HTML / CSS Themes and Templates](https://www.stubbornjava.com/best-selling-html-css-themes-and-website-templates)\r\n\r\n# Libraries\r\n## [SLF4J and Logback for Logging](https://www.stubbornjava.com/posts/logging-in-java-with-slf4j-and-logback)\r\nSLF4J is fairly standard and we chose to use Logback as our underlying implementation.\r\n\r\n## [Typesafe Config For Configuration](https://www.stubbornjava.com/posts/environment-aware-configuration-with-typesafe-config)\r\nTypesafe config is a clean lightweight immutable configuration library. It offers several formats such as `.properties`, `.yml`, `.json` as well as a human friendly json super set. It handles configuration inheritance, includes, data types (string, boolean, int, long, double, durations, arrays, ...), variabe substitution and many more features. [Typesafe Config examples](https://www.stubbornjava.com/posts/typesafe-config-features-and-example-usage)\r\n\r\n## Jackson for JSON\r\n* [Practical Jackson ObjectMapper Configuration](https://www.stubbornjava.com/posts/practical-jackson-objectmapper-configuration)\r\n* [Somewhat Deterministic ObjectMapper](https://www.stubbornjava.com/posts/creating-a-somewhat-deterministic-jackson-objectmapper)\r\n\r\n## [Embedded Undertow Web Server](https://www.stubbornjava.com/posts/java-hello-world-embedded-http-server-using-undertow)\r\nUndertow is a very fast low level non blocking web server written in Java. It is very lightweight and has a very clean API that should be relatively easy for anyone who knows HTTP to pick up. Most custom code will be in the form of an HttpHandler which is a simple interface that can be used in a variety of ways.\r\n* [Writing Custom HttpHandlers](https://www.stubbornjava.com/posts/undertow-writing-custom-httphandlers)\r\n* [Url Routing in Undertow](https://www.stubbornjava.com/posts/url-routing-with-undertow-embedded-http-server)\r\n* [Handling Exceptions in Undertow](https://www.stubbornjava.com/posts/handling-exceptions-in-undertow-with-composition)\r\n* [Creating Middleware in Undertow](https://www.stubbornjava.com/posts/logging-gzip-blocking-exception-handling-metrics-middleware-chaining-in-undertow)\r\n* [Simple REST server in Undertow](https://www.stubbornjava.com/posts/lightweight-embedded-java-rest-server-without-a-framework)\r\n* [Virtual Hosting in Undertow](https://www.stubbornjava.com/posts/virtual-hosting-in-undertow-s-embedded-java-web-server)\r\n* [Webpack and npm with Java](https://www.stubbornjava.com/posts/webpack-and-npm-for-simple-java-8-web-apps)\r\n* [Sharing routes and running multiple webservers in a single JVM](https://www.stubbornjava.com/posts/sharing-routes-and-running-multiple-java-services-in-a-single-jvm-with-undertow)\r\n* [Configuring Security Headers in Undertow](https://www.stubbornjava.com/posts/configuring-security-headers-in-undertow)\r\n* [Circuit Breaking HttpHandler](https://www.stubbornjava.com/posts/increasing-resiliency-with-circuit-breakers-in-your-undertow-web-server-with-failsafe)\r\n* [Creating a non-blocking delay in the Undertow Web Server for Artificial Latency](https://www.stubbornjava.com/posts/creating-a-non-blocking-delay-in-the-undertow-web-server-for-artificial-latency)\r\n\r\n## Metrics (Dropwizard Metrics, Grafana, Graphite)\r\n* [Monitoring your JVM with Dropwizard Metrics](https://www.stubbornjava.com/posts/monitoring-your-jvm-with-dropwizard-metrics)\r\n* [Grafana Cloud Dropwizard Metrics Reporter](https://www.stubbornjava.com/posts/grafana-cloud-dropwizard-metrics-reporter)\r\n\r\n## OkHttp for HTTP Client\r\n* [OkHttp Example REST client](https://www.stubbornjava.com/posts/okhttp-example-rest-client)\r\n* [OkHttp Logging Interceptors](https://www.stubbornjava.com/posts/okhttpclient-logging-configuration-with-interceptors)\r\n* [OkHttpClient Trust All SSL Certificates](https://www.stubbornjava.com/posts/okhttpclient-trust-all-ssl-certificates)\r\n* [Web Scraping with OkHttp and jsoup](https://www.stubbornjava.com/posts/web-scraping-in-java-using-jsoup-and-okhttp)\r\n\r\n## [HikariCP for JDBC Connection Pooling](https://www.stubbornjava.com/posts/database-connection-pooling-in-java-with-hikaricp)\r\nHikariCP is a very fast lightweight Java connection pool. The API and overall codebase is relatively small (A good thing) and highly optimized. It also does not cut corners for performance like many other Java connection pool implementations.\r\n\r\n## Uility Classes / Extras\r\n* [Password Hashing with BCrypt](https://www.stubbornjava.com/posts/hashing-passwords-in-java-with-bcrypt)\r\n* [XML sitemaps for SEO](https://www.stubbornjava.com/posts/creating-xml-sitemaps-in-java)\r\n* [Lazy loading and caching objects in Java with Guava's Suppliers.memoize](https://www.stubbornjava.com/posts/lazy-loading-and-caching-objects-in-java-with-guava-s-suppliers-memoize)\r\n* [Reading File Resources with Guava](https://www.stubbornjava.com/posts/reading-file-resources-with-guava)\r\n\r\n# Sites Built With This Method\r\n* [StubbornJava](https://www.stubbornjava.com/)\r\n* [QuickDraw](https://quickdraw.onsightdigitalsolutions.com/about)\r\n* [DeckHandHQ](https://www.deckhandhq.com)\r\n","funding_links":[],"categories":["terraform"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStubbornJava%2FStubbornJava","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FStubbornJava%2FStubbornJava","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStubbornJava%2FStubbornJava/lists"}