{"id":40634502,"url":"https://github.com/steinarb/sampleapp","last_synced_at":"2026-01-21T07:43:54.672Z","repository":{"id":65387843,"uuid":"390293367","full_name":"steinarb/sampleapp","owner":"steinarb","description":"Barebones sample application for a karaf webapp with a react.js frontend, backed by an SQL database, set up with liquibase, and with authentication and authorization provided by apache shiro","archived":false,"fork":false,"pushed_at":"2026-01-10T18:53:42.000Z","size":1867,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-11T02:14:46.380Z","etag":null,"topics":["bootstrap","bootstrap4","javascript","jersey","karaf","liquibase","npm","osgi","pax-web","pax-web-whiteboard","react","rest-api","webapp","webpack"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/steinarb.png","metadata":{"files":{"readme":"README.org","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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-07-28T09:31:18.000Z","updated_at":"2026-01-10T18:53:45.000Z","dependencies_parsed_at":"2025-12-24T13:06:25.863Z","dependency_job_id":null,"html_url":"https://github.com/steinarb/sampleapp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/steinarb/sampleapp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinarb%2Fsampleapp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinarb%2Fsampleapp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinarb%2Fsampleapp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinarb%2Fsampleapp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/steinarb","download_url":"https://codeload.github.com/steinarb/sampleapp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinarb%2Fsampleapp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28629916,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T04:47:28.174Z","status":"ssl_error","status_checked_at":"2026-01-21T04:47:22.943Z","response_time":86,"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":["bootstrap","bootstrap4","javascript","jersey","karaf","liquibase","npm","osgi","pax-web","pax-web-whiteboard","react","rest-api","webapp","webpack"],"created_at":"2026-01-21T07:43:51.260Z","updated_at":"2026-01-21T07:43:54.657Z","avatar_url":"https://github.com/steinarb.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"* Sampleapp\n\nThis is a barebones sample application for a multi-module, multi-bundle apache karaf web application.\n\nIntended to make it simple to start a new webapp.\n\nThe application database has a table \"accounts\" listing the users that are allowed to log into the database.  It also has some tables supporting a simple counter application (the increment step size for the counter for each logged in user, and the current count for each user).\n\nHighlights of the app:\n - Uses the [[https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.http.whiteboard.html][OSGi HTTP whiteboard]] to register servlets as services and give them a web context and paths\n - [[https://www.postgresql.org][react.js]] frontend, using [[https://redux.js.org][redux]] for state management (set up using [[https://redux-toolkit.js.org][redux-toolkit]])\n - [[https://getbootstrap.com/docs/5.0/getting-started/introduction/][bootstrap v5]] styling of the frontend\n - [[https://en.wikipedia.org/wiki/Internationalization_and_localization][i18n/l11n]] support (using redux on the frontend and [[https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ResourceBundle.html][Java resource bundles]] on the backend) with English and Norwegian as the languages\n - [[https://en.wikipedia.org/wiki/Jakarta_RESTful_Web_Services][JAX-RS]] REST Service support provided by [[https://eclipse-ee4j.github.io/jersey/][eclipse jersey]]\n - authentication and authorization provided by [[https://shiro.apache.org][apache shiro]] (implemented in [[https://github.com/steinarb/authservice][authservice]], but in theory anything that provides a [[https://shiro.apache.org/realm.html][shiro Realm]] as an OSGi service and provides a shiro role named sampleappuser can give access to the application)\n - JDBC configuration and setup using [[https://ops4j1.jira.com/wiki/spaces/PAXJDBC/pages/61767710/Create+DataSource+from+config][PAX JDBC config]] (provides a Datasource OSGi service using configuration only and no code needed)\n - Database migration support provided by [[https://liquibase.org][liquibase]] with sample database setups for [[https://db.apache.org/derby/][apache derby]] and [[https://www.postgresql.org][PostgreSQL]]\n\nAll user information, outside of the username, i.e. full name, email, comes from an injected OSGi service of type [[https://www.javadoc.io/doc/no.priv.bang.osgiservice/osgiservice/latest/no/priv/bang/osgiservice/users/UserManagementService.html][UserManagementService]] provided by the [[https://github.com/steinarb/authservice][authservice]].\n\nThe username/password combinations of users in the test db version of authservice, are:\n| username | password  | authorized for sampleapp |\n|----------+-----------+--------------------------|\n| jad      | 1ad       | yes                      |\n| jod      | johnnyBoi | no                       |\n\n** Development status\n[[https://github.com/steinarb/sampleapp/actions/workflows/sampleapp-maven-ci-build.yml][file:https://github.com/steinarb/sampleapp/actions/workflows/sampleapp-maven-ci-build.yml/badge.svg]]\n[[https://coveralls.io/github/badges/shields?branch=master][file:https://coveralls.io/repos/github/badges/shields/badge.svg?branch=master]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sampleapp][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sampleapp\u0026metric=alert_status#.svg]]\n\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sampleapp][file:https://sonarcloud.io/images/project_badges/sonarcloud-white.svg]]\n\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sampleapp][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sampleapp\u0026metric=sqale_index#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sampleapp][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sampleapp\u0026metric=coverage#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sampleapp][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sampleapp\u0026metric=ncloc#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sampleapp][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sampleapp\u0026metric=code_smells#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sampleapp][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sampleapp\u0026metric=sqale_rating#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sampleapp][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sampleapp\u0026metric=security_rating#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sampleapp][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sampleapp\u0026metric=bugs#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sampleapp][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sampleapp\u0026metric=vulnerabilities#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sampleapp][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sampleapp\u0026metric=duplicated_lines_density#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sampleapp][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sampleapp\u0026metric=reliability_rating#.svg]]\n\n** Installing the sample application\n\nFirst clone and build the sample application:\n#+begin_example\n  mkdir -p ~/git/\n  cd ~/git/\n  git clone https://github.com/steinarb/sampleapp.git\n  cd ~/git/sampleapp/\n  mvn install\n#+end_example\n\nThen give the following commands to the karaf console:\n#+BEGIN_EXAMPLE\n  feature:repo-add mvn:no.priv.bang.sampleapp/karaf/LATEST/xml/features\n  feature:install sampleapp-with-derby\n#+END_EXAMPLE\n\nThen:\n 1. open http://localhost:8181/sampleapp in a web browser\n 2. log in as user \"jad\" with password \"1ad\"\n 3. click on counter and use \"-\" and \"+\" to change the value\n 4. try editing the step size, wait a few seconds and then observe that \"+\" and \"-\" change the value with the step size\n 5. Navigate to the top page and log out\n 6. Log in as user \"jod\" with password \"johnnyBoi\" and observe that you end in a \"not authorized page\" (the user exists but do not have the role of the app)\n 7. Log out and log back in as user \"jad\", navigate to the \"counter\" page, and observe that the count is like you left it (the count is persisted in the database)\n\n** Creating a new application based on the sample app\n\nUsing the [[https://maven.apache.org/archetype/maven-archetype-plugin/i][maven archetype plugin]] to adapt the sample project to a new project is simpler than hand editing the sample project and moving all packages and module names, but it doesn't take you all the way (it doesn't rename Java classes and doesn't fix up the shiro.ini files).\n\nTo create a new project called \"mynewapp\":\n 1. First clone the sample project and create an archetype from it (it's best to create an archetype from a fresh clone, because then the archetype won't contain unnecessary files like IDE config files and binary files from the build)\n    #+begin_example\n      cd /tmp\n      git clone https://github.com/steinarb/sampleapp.git\n      cd sampleapp\n      mvn archetype:create-from-project -Darchetype.filteredExtensions=javaw\n      cd target/generated-sources/archetype/\n      mvn install\n    #+end_example\n 2. Create the new project from the archetype (the -DgroupId, -DartifactId, and -Dversion arguments are the GAV values of the new project)\n    #+begin_example\n      mkdir -p ~/git/\n      cd ~/git/\n      mvn archetype:generate -DarchetypeCatalog=local -DarchetypeGroupId=no.priv.bang.sampleapp -DarchetypeArtifactId=sampleapp-archetype -DgroupId=com.mycompany.mynewapp -DartifactId=mynewapp -Dversion=1.0.0-SNAPSHOT -DinteractiveMode=false\n    #+end_example\n 3. Fix the groupId for a karaf feature file dependency in the integration test maven module, and the dependency management for the master karaf feature repository, because these dependencies aren't handled by the archetype project generator:\n    #+begin_example\n      cd ~/git/mynewapp/\n      sed -i 's/no\\.priv\\.bang\\.sampleapp/com.mycompany.mynewapp/gI' pom.xml */pom.xml\n    #+end_example\n 4. Fiks replace version in the dependency management section of the parent pom with ${project.version}\n    #+begin_example\n      sed -i 's/^                \u003cversion\u003e1.0.0-SNAPSHOT/                \u003cversion\u003e${project.version}/gI' pom.xml\n    #+end_example\n 5. Fix up some files that aren't handled by the archetype filtering (don't know why everything in the pom files aren't filtered)\n    #+begin_example\n      sed -i 's/sampleapp/mynewapp/g' */src/main/resources/shiro.ini\n      sed -i 's/sampleapp/mynewapp/g' */src/test/resources/test.shiro.ini\n      sed -i 's/sampleapp/mynewapp/gI' */pom.xml\n      find . -name \\*.js | xargs sed -i 's/sampleapp/mynewapp/g'\n    #+end_example\n 6. Add a .gitignore file (there is a bug in maven-resources-plugin that excludes this file from archetypes):\n    #+begin_example\n      ,*.iml\n      ,*.log\n      .classpath\n      .idea/\n      .project\n      .settings/\n      /.metadata/\n      /TAGS\n      node_modules/\n      target/\n    #+end_example\n 7. Test build the project with \"mvn install\" (it should build without any errors)\n    #+begin_example\n      cd ~/git/mynewapp/\n      mvn install\n    #+end_example\n 8. Open the java maven modules of the mynewapp project, in a Java IDE (eclipse or IntelliJ), and use the refactoring of the IDE to rename classes with names starting with \"Sampleapp\" into classes starting with \"Mynewapp\" (this is the step that the archetype can't handle, but at least the classes are already in packages they are supposed to be in for the new application), classnames to change:\n    #+begin_example\n      SampleappServiceProvider\n      SampleappServiceProviderTest\n      SampleappService\n      SampleappServiceTest\n      SampleappException\n      SampleappExceptionTest\n      SampleappConstants\n      SampleappLiquibase\n      SampleappLiquibaseTest\n      SampleappTestDbLiquibaseRunner\n      SampleappTestDbLiquibaseRunnerTest\n      SampleappProductionDbLiquibaseRunner\n      SampleappProductionDbLiquibaseRunnerTest\n      SampleappWebApi\n      SampleappWebApiTest\n      SampleappServlet\n      SampleappServletTest\n      SampleappServletContextHelper\n      SampleappShiroFilter\n      SampleappShiroFilterTest\n      SampleappIntegrationTest\n      SampleappTestdata\n      SampleappTestdataTest\n    #+end_example\n 9. Build mynewapp from the top with \"mvn clean install\" (\"clean\" is to get rid of .class files with the old names)\n    #+begin_example\n      cd ~/git/mynewapp/\n      mvn clean install\n    #+end_example\n 10. Fix some Java class member names that hasn't been touched by the renaming (OSGi service injection setter and constants):\n     #+begin_example\n       find . -name \\*.java | xargs sed -i 's/Sampleapp/Mynewapp/g'\n       find . -name \\*.java | xargs sed -i 's/SAMPLEAPP/MYNEWAPP/g'\n     #+end_example\n 11. Fix some leftover Sampleapp texts\n     #+begin_example\n       find . -name pom.xml | xargs sed -i 's/Sampleapp/Mynewapp/g'\n       find . -name feature.xml | xargs sed -i 's/Sampleapp/Mynewapp/g'\n       find . -name \\*.html | xargs sed -i 's/Sampleapp/Mynewapp/g'\n       find . -name package.json | xargs sed -i 's/Sampleapp/Mynewapp/g'\n       find . -name package-lock.json | xargs sed -i 's/Sampleapp/Mynewapp/g'\n       find ./mynewapp.web.frontend/src/main/frontend/src -name \\*.js | xargs sed -i 's/Sampleapp/Mynewapp/g'\n     #+end_example\n 12. Fix copyright dates\n     #+begin_example\n       find . -name *.xml | xargs sed -i 's/2021-2022/2025/g'\n       find . -name *.java | xargs sed -i 's/2021-2022/2025/g'\n       find . -name *.xml | xargs sed -i 's/2021-2023/2025/g'\n       find . -name *.java | xargs sed -i 's/2021-2023/2025/g'\n       find . -name *.java | xargs sed -i 's/2019-2024/2025/g'\n       find . -name *.java | xargs sed -i 's/2021-2024/2025/g'\n       find . -name *.xml | xargs sed -i 's/2021-2025/2025/g'\n       find . -name *.java | xargs sed -i 's/2021-2025/2025/g'\n       find . -name *.xml | xargs sed -i 's/2021/2025/g'\n       find . -name *.java | xargs sed -i 's/2021/2025/g'\n     #+end_example\n 13. Install mynewapp in a karaf instance\n     #+begin_example\n       feature:repo-add mvn:com.mycompany.mynewapp/karaf/LATEST/xml/features\n       feature:install mynewapp-with-derby\n     #+end_example\n 14. Verify that the application is running on http://localhost:8181/mynewapp\n\n** Configuring a new default locale\n\nOut of the box, the sample application supports two locales: nb_NO (Norwegian bokmål) and en_GB (UK English).\n\nThe locale texts are provided by a Java resource bundle, and new languages can be added by adding them to the bundle and to the available locales returned by the SampleappService.\n\nThe default locale is nb_NO.\n\nIt is possible to persistently configuring the default locale to en_GB with the following commands in the karaf console command line:\n#+begin_example\n  config:edit no.priv.bang.sampleapp.backend.SampleappServiceProvider\n  config:property-set defaultlocale en_GB\n  config:update\n#+end_example\n\n/Note/! The name of the config file will change when the package name and classname of the class changes in a new application based on this one, so adjust the command example accordingly.\n** License\n\nThis software is licensed with the Apache License v2.  See the file LICENSE for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteinarb%2Fsampleapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsteinarb%2Fsampleapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteinarb%2Fsampleapp/lists"}