miles2run.org is an easy way to track your running activities and share with friends and families. Day-based or distance-based goals can be created and then tracked. It also allows to create community run goals and have multiple runners participate and track their activities towards that goal. You can also find out local runners and connect with them.
The project was started to help track running activities for #JavaOneStreak. The goal was to run at least a mile every day all the way until JavaOne and use this website to track the runs. There are tons of sophisticated applications and websites that allow you to track running activity. Most of them provide integration with your GPS watch, phone GPS, and other fancy features. Some of them even allow creating a group but none of them is based on Java
The application is hosted as a website and built using HTML5 and Java EE 7. The landing page provides a summary of total runners, their city/country, miles, and hours logged so far.
The website can be viewed on a desktop, tablet, or a cell phone. The runners can login to the website using common social brokers such as Facebook, Google, and Twitter.
Any body can click on “Community Runs” on the top-right corner to see what all group runs have been created so far. These can only be created by an administrator. The group run page for JavaOne shows how many runners have joined this run and other statistics.
Each runner is presented with a dashboard showing how much distance they’ve run so far and total/completed/remaining/missed days.
A visual representation of the progress and a heat map of the activity calendar is shown:
A line chart of mileage over the days is shown:
And then a summary of activities over the past months is shown as well:
Runners also have the opportunity to follow other runners and track their activities.
Here is a conceptual view of the application:
And here is a technology view of the application:
Here is a brief description of the technology stack:
- Thymeleaf template engine views rendered by JAX-RS
- Social brokering using native APIs for Facebook, Google, Twitter
- Middle Tier
@StatelessEJB for all transactional JPA interactions,
@Asynchronousfor posting status to social networks
- JAX-RS for exposing REST endpoints.
ContainerResponseFilterfor security for cross-cutting concerns like authentication, injecting profile, and CORS.
- Bean Validation constraints in JAX-RS resources.
- Bean discovery mode=”all”
- CDI producers for creating
EntityManagersand other configuration objects like Redis connection pool objects or MongoDB configuration object. All NoSQL services are created
- Using native drivers for Redis and MongoDB. Jedis is being used for Redis and MongoDB Java driver is used for MongoDB. CDI services wrap these driver API and expose business functionalities that other layers could use.
- JPA + Bean Validation. Database scripts are generated from JPA model, added to source control, manually applied to the database. Using
@Indexand Entity Graph.
- Servlets are used for callback URLs for social brokers.
- Error pages are configured using
- MySQL is used for all business entities like Activity, Goal, User Profile etc. Redis is used for storing counters and timeline data. MongoDB is used for location-based user recommendations and follower/following recommendations.
- CDI producers for creating
Technologies from outside the platform:
- Google Geocoding API to convert Location Text to latitude and longitude
- Jadira usertype for storing dates in UTC
- Joda-Time for working with dates
- Thymeleaf was used instead of JavaServer Faces because:
- Allows JAX-RS to be used as an MVC framework to render server side HTML pages and exposing REST services.
- This application is a Single Page application built using AngularJS. So, we needed a lightweight approach to render server side pages. JAX-RS along with Thyemleaf render the main HTML 5 page and then we use AngularJS to render different partials/views on that page. For example, the main home page is rendered by JAX-RS and Thymeleaf. When you work with different sections of this page all of them are part of a SPA managed by AngualarJS.
- Thymeleaf documents are valid HTML 5 documents so you can work with them offline for static prototyping.
- Redis is used for storing all the counters like number of runners, cities, counters specific to goal like total distance covered in a goal etc. To avoid lots of read/write from the database, an an in-memory database is used so all the write and read operations are very performant. Redis counters are atomic, which means there are no concurrency issues associated with it. INCR andINCRBY Redis operations are used to update counters.
- MongoDB is used for location data.
- JDK 8
- IntelliJ 13.1 with Maven
- Wildfly 8.1.0.Final – Development was done using a local WildFly instance and then pushed to scalable WildFly instances on OpenShift for deployment. HA Proxy is used as the load balancer.The advantage of working with OpenShift is that there is no OpenShift specific code in your application. So, it’s the same application that work locally that is deployed to test and production environment. You just have to use environment variables to abstract out environment specific configuration.
- Use Jenkins for Continuous Integration and manage deployments
- JPA 2.1 converter instead of Jadira
- Keycloak instead of native social broker
- Opensource the application
Wish list for Java EE 8
- Integration with OAuth providers
- A real MVC framework with support for pluggable template engines
- Seamless working with NoSQL databases
Or if you want to be on the bleeding edge, check out WildFly 9.0.
Many thanks to Shekhar Gulati (@shekhargulati) for authoring the application and providing all the answers!
Are you using Java EE 7 and WildFly to deploy your projects ? Would love to feature you here! Send me an email or leave a comment on the blog.