<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pathik Desai</title>
    <description>The latest articles on DEV Community by Pathik Desai (@pathiknd).</description>
    <link>https://dev.to/pathiknd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F386039%2Fecff2f5b-870f-4ca9-b6dc-3b1ea98b4062.jpg</url>
      <title>DEV Community: Pathik Desai</title>
      <link>https://dev.to/pathiknd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pathiknd"/>
    <language>en</language>
    <item>
      <title>Software Architecture Basics: What, How &amp; Why</title>
      <dc:creator>Pathik Desai</dc:creator>
      <pubDate>Mon, 26 Sep 2022 14:28:14 +0000</pubDate>
      <link>https://dev.to/pathiknd/software-architecture-primer-4boj</link>
      <guid>https://dev.to/pathiknd/software-architecture-primer-4boj</guid>
      <description>&lt;p&gt;Architecture and Design are widely used terms in software engineering. Every software has some architecture. But what is Software Architecture and why is it given so much importance? Or is it really important? The goal of this write-up is to gain a better understanding with help of some examples.&lt;/p&gt;

&lt;p&gt;Let's start with basics.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Software Architecture?
&lt;/h2&gt;

&lt;p&gt;There are many definitions of Software Architecture. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Software_architecture"&gt;Wikipedia&lt;/a&gt; says &lt;em&gt;"Software architecture refers to the fundamental structures of a software system and the discipline of creating such structures and systems"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://martinfowler.com/architecture/"&gt;Martin Fowler&lt;/a&gt; has defined architecture as &lt;em&gt;"the decisions you wish you could get right early in a project&lt;/em&gt; and &lt;em&gt;Architecture is about the important stuff. Whatever that is."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There will be many more definitions. They all are true, but I have found the description in &lt;a href="https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164"&gt;Clean Architecture&lt;/a&gt; by &lt;a href="http://cleancoder.com/files/about.md"&gt;Uncle Bob&lt;/a&gt; easier to start understanding the concept. Here is my explanation based on that:&lt;/p&gt;

&lt;p&gt;There are two aspects (or "value" as Uncle Bob says) of a software:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Behavior&lt;/strong&gt;: the reason for the software to exist like an email client to send and receive emails, a calculator to perform calculations, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shape / Structure&lt;/strong&gt;: it is the foundation on which features (that provide behavior) are built.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Behaviors will change with time as the software needs to adapt to growing and changing user needs. &lt;em&gt;A good architecture will provide shape / structure that makes the evolution of behaviors easier, faster and less expensive&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Architecture's goals are to make it easy to understand (for a developer), develop, maintain (change), deploy and operate a software.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A lot has been said in few lines! It will become clear as we go further.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Design?
&lt;/h2&gt;

&lt;p&gt;The difference between Software Architecture and Design is confusing because they both are mixed and sometimes there is no clear differentiation. But still let's try to understand what is called Design.&lt;/p&gt;

&lt;p&gt;Architecture is about shape / structure which is fundamental and difficult to change once done. Design is things that are built on the foundation and things that can be changed with relatively less difficultly.&lt;/p&gt;

&lt;p&gt;Let's try to understand with an example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An application has default system settings and user settings. User settings override default system settings. Default system settings are configurable via database and environment variables. Environment variables take priority over database config.&lt;/li&gt;
&lt;li&gt;To implement this requires deciding many things like:

&lt;ol&gt;
&lt;li&gt;Configuration Parameter naming standardization&lt;/li&gt;
&lt;li&gt;Database schema to store configuration&lt;/li&gt;
&lt;li&gt;APIs / Interface used by other parts of system to fetch and update configuration&lt;/li&gt;
&lt;li&gt;Classes and their relationships implementing the behaviour required for configurations&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;#1, #2 and #3 are things that are more expensive to change once implemented and deployed. So they are &lt;strong&gt;Architectural Decisions&lt;/strong&gt;. #4 can be changed relatively easily even after implementation so it can be considered a &lt;strong&gt;Design Decision&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Process of Architecting
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Architecture&lt;/em&gt; in a way is &lt;strong&gt;a set of decisions taken in a given scenario&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Most of the times, something can be done in multiple ways, but the &lt;em&gt;Architecture&lt;/em&gt; selects one option from that. That &lt;strong&gt;choice of one option&lt;/strong&gt; is the &lt;strong&gt;Architectural Decision&lt;/strong&gt;. E.g.,

&lt;ul&gt;
&lt;li&gt;There are multiple protocols to build an API: REST, GraphQL, SOAP.&lt;/li&gt;
&lt;li&gt;The decision to use GraphQL is the Architectural Decision.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;So next questions should be how are these decisions made? Inputs to Architectural Decision Making:

&lt;ol&gt;
&lt;li&gt;Requirements &lt;/li&gt;
&lt;li&gt;Architectural Characteristics (AC) (or Non-Functional Requirements) derived based on requirements and business domain. E.g.,

&lt;ul&gt;
&lt;li&gt;For a stock trading platform, Performance and Reliability are important ACs.&lt;/li&gt;
&lt;li&gt;For a news aggregation portal, Responsiveness is important - meaning immediately load first 5 stories and load remaining stories asynchronously, so user doesn't have to wait longer to start consuming the content. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Implicit ACs: things that nobody will ask for but always expect like Security, Maintainability, etc.&lt;/li&gt;
&lt;li&gt;Available resources: budget (cost), skills and time. Example:

&lt;ul&gt;
&lt;li&gt;It is identified that writing a serverless function (AWS Lambda) is good choice to perform some background tasks.&lt;/li&gt;
&lt;li&gt;NodeJS may be the right choice to write a serverless function but do we have skills in the team to build it within the time we have to release the feature?&lt;/li&gt;
&lt;li&gt;We don't have NodeJS developers but we have Java developers, so is it possible to use Java to write a serverless function?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Most Architectural Decisions are trade-offs. They have some bad outcomes, but still it may be &lt;em&gt;right decision&lt;/em&gt; for the given circumstances. If we can live with it, it is easier otherwise we have to try to mitigate its effects. E.g.,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing a serverless function (AWS Lambda) in Java has problem of &lt;a href="https://mikhail.io/serverless/coldstarts/aws/"&gt;Cold Start&lt;/a&gt; because JVM takes at least few hundred milliseconds to start-up.&lt;/li&gt;
&lt;li&gt;So we have following options. Each has its negative impact but we have to select the one &lt;em&gt;right for current circumstances&lt;/em&gt;:

&lt;ol&gt;
&lt;li&gt;Since the functions will be used in background processing so we decide to live with few milliseconds of performance hit for now and revisit this later if it becomes a serious issue.&lt;/li&gt;
&lt;li&gt;In case we cannot afford performance hit, we have to provision at least 1 (or more depending on load) Lambda instance to be active all the time. But this will add to Cost. &lt;/li&gt;
&lt;li&gt;Train a developer on NodeJS and then write function in NodeJS. But this will impact timeline.&lt;/li&gt;
&lt;li&gt;Find an alternate to serverless function.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Output of Architecting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documentation with reasoning and decisions. It can be diagrams, write-ups, specs, etc.&lt;/li&gt;
&lt;li&gt;Common artefacts:

&lt;ul&gt;
&lt;li&gt;Components and relationships between them&lt;/li&gt;
&lt;li&gt;Shared libraries and interfaces&lt;/li&gt;
&lt;li&gt;Deployment view &lt;/li&gt;
&lt;li&gt;Security scheme - authentication, authorization, secrets management&lt;/li&gt;
&lt;li&gt;API Schema&lt;/li&gt;
&lt;li&gt;DB Schema&lt;/li&gt;
&lt;li&gt;Guidelines like naming conventions, exception handling practices, logging conventions, etc. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Case Study
&lt;/h2&gt;

&lt;p&gt;Let's walkthrough the journey of an application to understand these concepts with an example.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Product Manager (PM)&lt;/em&gt; and &lt;em&gt;Engineering Team (ET)&lt;/em&gt; discuss requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage: Building MVP
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;PM&lt;/em&gt;: We need to build a mobile app that will allow users to send SMS in bulk and check the status of the delivery. Users can manage list of recipients by uploading a CSV or manage via the App.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ET&lt;/em&gt;: Do we need to send SMS for each request immediately on receiving request? &lt;/p&gt;

&lt;p&gt;&lt;em&gt;PM&lt;/em&gt;: No, we don't have to do that now. We put the request in queue and we process requests one by one. Expectation is that we will process it at least within an hour of user submitting the request. This is MVP so we will keep it simple.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ET&lt;/em&gt;: How will the user on-board and sign-in?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PM&lt;/em&gt;: They will use their mobile number. We will send an OTP and verify the number.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ET&lt;/em&gt; comes up with an architecture for MVP and produces artefacts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Components&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qtLwZNxu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vhp35h50ghnzznw2b40j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qtLwZNxu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vhp35h50ghnzznw2b40j.png" alt="Components Diagram" width="741" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YcquAkUC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yqlh0tc1bjyrmf4i287.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YcquAkUC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yqlh0tc1bjyrmf4i287.png" alt="Deployment Diagram" width="687" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The architecting process would produce other artefacts like Database Schema, Security Scheme, etc., but we are only including things relevant to the discussion.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  1 month after MVP release
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;PM&lt;/em&gt;: We have got an enterprise customer who is interested in using our services. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;ET&lt;/em&gt;: That's great!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PM&lt;/em&gt;: They right now use another provider. They generate a CSV file with requests at scheduled frequency. This file is uploaded to a shared location and the service provider processes the file to send messages. They are interested in trying out our service if they do not have to make any changes to their implementation. Can we make it work?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ET&lt;/em&gt;: It should be possible..Let us think about it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ET&lt;/em&gt; comes up with a solution that can be implemented quickly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Components&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A new component &lt;em&gt;FileRequestService&lt;/em&gt; is added that will read files and create requests from that. This was possible because core domain logic to manage requests, recipients, etc. was implemented in &lt;em&gt;BulkSenderDomainLib&lt;/em&gt; so it can be re-used easily from any part of the system. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0_TA736d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5mte2rt63k7cr269owc3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0_TA736d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5mte2rt63k7cr269owc3.png" alt="Component Diagram v2.0" width="741" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r1aKpimf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7cvbmxzmp8tq2i42v3ej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r1aKpimf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7cvbmxzmp8tq2i42v3ej.png" alt="Deployment v2.0" width="687" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What went well?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Breaking down system in modules allowed a new requirement to be accommodated very easily and quickly. This kind of requirement was not expected during MVP, but the Architecture was able to handle it.&lt;/p&gt;

&lt;h3&gt;
  
  
  6 months after MVP
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;PM&lt;/em&gt;: There is lot of interest for our service. Customers really want to use it but we are getting lot of complaints that the messages are delivered after hours. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;ET&lt;/em&gt;: Because we are getting lot of requests...&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PM&lt;/em&gt;: But we need to fix this.In fact, we also want to introduce a quick delivery paid plan. We think we will get customers ready to pay for an immediate delivery commitment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ET&lt;/em&gt;: That's going to require a lot of work.. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;PM&lt;/em&gt;: Why..??&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ET&lt;/em&gt;: We kept is &lt;em&gt;simple&lt;/em&gt; for the MVP. We did not provision for scaling for such load.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PM&lt;/em&gt;: We better do it right now!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What went wrong?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;ET&lt;/em&gt; did not identify Scalability as AC\NFR in request processing in the original MVP architecture&lt;/strong&gt;. That is now causing a problem when the solution needs to scale quickly. This lapse can be costly because it can either force a half-baked solution in hurry or delay business plans.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Should &lt;em&gt;ET&lt;/em&gt; always design for scale even when they don't know what is going to be the scale?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Its a &lt;em&gt;trade-off&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;a. Building for scalability will add complexity to the solution meaning more time to release. &lt;/p&gt;

&lt;p&gt;b. On the other hand, there may be kind of problem we just went to through.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There is no right or wrong approach&lt;/em&gt;. If MVP doesn't work, doing a quick release saved effort so (b) would be the right thing. &lt;/p&gt;

&lt;p&gt;That's where the &lt;strong&gt;Architectural Decision Making&lt;/strong&gt; is required to find a balance between &lt;em&gt;Long Term Goals&lt;/em&gt; and &lt;em&gt;Short-term Needs&lt;/em&gt; working with all stakeholders.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  In the end..
&lt;/h2&gt;

&lt;p&gt;There is no universally accepted definition or scope of Software Architecture. It also evolves continuously with change in technology e.g., Cloud has added lot of new possibilities that widens the scope of Architecture. We have tried to understand &lt;strong&gt;what can be considered Software Architecture&lt;/strong&gt;. And now if you go back and read all definitions of Software Architecture, you may understand them better.&lt;/p&gt;

&lt;p&gt;Instead of exactly defining what is Software Architecture, it is important get a good understanding of &lt;strong&gt;Process of Architecting&lt;/strong&gt; and &lt;strong&gt;Importance of making good architecture and design decisions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is a vast topic with various perspectives. Lot of the insights come with experience. I have presented my understanding. Please comment if there is anything you would like to add (or remove too :)). Thanks for reading!&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164"&gt;Clean Architecture&lt;/a&gt; by Robert C. Martin&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.amazon.in/Fundamentals-Software-Architecture-Engineering-Approach-ebook/dp/B0849MPK73/ref=sr_1_3?crid=271BK9XDEO9DN&amp;amp;keywords=software+architecture&amp;amp;qid=1664192629&amp;amp;qu=eyJxc2MiOiI0LjU2IiwicXNhIjoiMy45NiIsInFzcCI6IjMuODAifQ%3D%3D&amp;amp;sprefix=%2Caps%2C1173&amp;amp;sr=8-3"&gt;Fundamentals of Software Architecture: An Engineering Approach&lt;/a&gt; by Mark Richards, Neal Foad&lt;/p&gt;

&lt;p&gt;&lt;a href="https://c4model.com/"&gt;C4 Model&lt;/a&gt; by Simon Brown - Component Diagram uses C4 template&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>programming</category>
    </item>
    <item>
      <title>Application Configuration from Operations Viewpoint</title>
      <dc:creator>Pathik Desai</dc:creator>
      <pubDate>Sat, 29 Aug 2020 11:00:43 +0000</pubDate>
      <link>https://dev.to/pathiknd/application-configuration-from-operations-viewpoint-491p</link>
      <guid>https://dev.to/pathiknd/application-configuration-from-operations-viewpoint-491p</guid>
      <description>&lt;p&gt;All software applications would have some configuration. This post is about seeing the configuration from operations viewpoint: its challenges and some methods to manage it better.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Operations here simply means the process of running a software application in any environment like Dev, Test, UAT, Prod, etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First let's understand which configuration is being discussed here and what are the challenges.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Problem
&lt;/h1&gt;

&lt;p&gt;Configuration give broadly two capabilities without modifying the software:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ability to change the behavior&lt;/li&gt;
&lt;li&gt;Provide inputs from outside to make the same software work in different environments or work with different attributes e.g., database connection settings to make it work with different instances of a Database.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Configurability increases complexity but it is required to quickly adapt to the changes especially in Software Products which have to cater to different use-cases in different types of environments. Configurability provides capability to meet those requirements quickly.&lt;/p&gt;

&lt;p&gt;The configurations will be of two types:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Settings set by the end users&lt;/li&gt;
&lt;li&gt;Configured by the Operations team&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;#1&lt;/strong&gt; is generally well documented and managed by the end users. &lt;strong&gt;#2&lt;/strong&gt; is where there are some challenges such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It often happens that during the process of development, configurations are added by developers and they are very familiar with what should be the correct values but the Operations team / person doesn't have or get that clarity.&lt;/li&gt;
&lt;li&gt;As a solution grows, number of configurations grow too and it becomes difficult if a new environment is to be set-up. One would often come across situations where only one or two people in the team can actually set-up the software in a new environment. This can be a serious bottleneck for Software Products where it can reduce the ability to quickly make the product available to customer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's understand this with an example of simple file processor of the Biller Org. File processor processes the daily transaction files uploaded by parteners who accept payments on behalf of the Biller Org and provide transaction details to the Biller Org so that the Biller Org can update its systems to reflect the payments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G1AMsX21--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9i24lcjygainck1tjnu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G1AMsX21--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9i24lcjygainck1tjnu5.png" alt="File Processing" width="505" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;File Processor does the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read files from FTP file share&lt;/li&gt;
&lt;li&gt;Update the database&lt;/li&gt;
&lt;li&gt;Store the original files to Archive, successfully processed to Success, files failed processing to Failed and the logs of each file processing to Log directories on a network share.&lt;/li&gt;
&lt;li&gt;It can be set-up to run in two modes (a) process each item in file as one transaction i.e. write failed item to Failed but keep processing (b) proess entire file as one transaction i.e. either entire file is processed successfully or entire file is marked failed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's see the configuration parameters we will need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Database connection settings&lt;/li&gt;
&lt;li&gt;FTP Share access settings&lt;/li&gt;
&lt;li&gt;Paths of Archive, Success, Failed and Log shares&lt;/li&gt;
&lt;li&gt;Flag to control the mode of transaction - File or Item&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This needs to be set-up in every environment and for each partner, and in a real system there would many such jobs. &lt;/p&gt;

&lt;h1&gt;
  
  
  Mitigation
&lt;/h1&gt;

&lt;p&gt;Configurability is beneficial and required so we can't completely do away with the problems discussed above, but there can be some ways it can be made more manageable as we see below - this is not an exhaustive list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documenting with configuration
&lt;/h2&gt;

&lt;p&gt;Document each parameter in the configuration file itself - or add a column in database if it is being kept in a database.&lt;/p&gt;

&lt;p&gt;Continuing with our example, the configuration file can be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# USE: Control transaction mode of the processing.&lt;/span&gt;
&lt;span class="c1"&gt;# EXPECTED VALUE:&lt;/span&gt;
&lt;span class="c1"&gt;#  ITEM - Consider each item as one transaction&lt;/span&gt;
&lt;span class="c1"&gt;#  FILE - Consider entire file to be one transaction&lt;/span&gt;
&lt;span class="na"&gt;app.transaction-mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ITEM&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# USE: Store original files after processing&lt;/span&gt;
&lt;span class="c1"&gt;# EXPECTED VALUE: Full path to the directory&lt;/span&gt;
&lt;span class="na"&gt;app.archive-path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;some path&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# USE: Store failed files after processing&lt;/span&gt;
&lt;span class="c1"&gt;# EXPECTED VALUE: Full path to the directory&lt;/span&gt;
&lt;span class="na"&gt;app.failed-path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;some path&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This could be made part of the Code Review process where a new configuration without enough documentation is not accepted.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This will make sure that anyone can get a good idea of what to do right in the place where the values need to be configured.&lt;/p&gt;

&lt;h2&gt;
  
  
  Convention over configuration
&lt;/h2&gt;

&lt;p&gt;Convention over configuration is used by many frameworks to reduce the amount of configuration \ boilerplate code required - all MVC frameworks follow this pattern. The same can applied in application configurations.&lt;/p&gt;

&lt;p&gt;In the above example, the number of configurations can be reduced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# USE: Control transaction mode of the processing. Set if you want to change Default.&lt;/span&gt;
&lt;span class="c1"&gt;# EXPECTED VALUE:&lt;/span&gt;
&lt;span class="c1"&gt;#  ITEM - Consider each item as one transaction&lt;/span&gt;
&lt;span class="c1"&gt;#  FILE - Consider entire file to be one transaction&lt;/span&gt;
&lt;span class="c1"&gt;# DEFAULT: ITEM.&lt;/span&gt;
&lt;span class="c1"&gt;# app.transaction-mode: ITEM&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# USE: Store output files after processing. Program will create Archive, Success, Failed and Log directory under this path.&lt;/span&gt;
&lt;span class="c1"&gt;# EXPECTED VALUE: Full path to the directory&lt;/span&gt;
&lt;span class="na"&gt;app.output-path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;some path&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reduction is due to following two conventions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Default transaction mode is assumed to be ITEM if it is not set. So you only configure the parameter, if you need to change the default. Default can be decided based on commonly expected value.&lt;/li&gt;
&lt;li&gt;Instead of taking four directory paths, take path of root and then always create directories under that: Archive, Success, Failed, Log. This will potentially reduce some flexibility, but improve maintainability.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Scripts / Tools to detect errors
&lt;/h2&gt;

&lt;p&gt;If you have an application that runs on 100s or 1000s of desktops (or simply machines irrespective of they are servers or desktops) and the configuration resides on those machines, it is very difficult to troubleshoot issues as you do not have access to the machine and can't check whether all the configuration parameters are correct or not. Having some script or utility that can scan the configuration and highlight any problems can greatly help the operations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AWS has a service named AWS Config which can be configured to monitor compliance to a desired configuration of your environment. It will highlight if it detects any violation from the desired state e.g., it is configured to monitor that only port 443 should be open on EC2 Instances so it will raise an alert if it finds some other port open on the server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Configuration in Containerized Deployments
&lt;/h1&gt;

&lt;p&gt;Containers are started from an image which has the application installed in it. Now, if configuration is included in the image along with application, an image is required for each environment - or each change to configuration.&lt;/p&gt;

&lt;p&gt;Therefore, configuration needs to be &lt;em&gt;externalized&lt;/em&gt;. Common pattern is to keep the configuration in a repository, vault, shared storage, etc. and provide the application access parameters to the store by setting environment variables in the container.&lt;/p&gt;

&lt;h1&gt;
  
  
  Configuration in Single Page Applications
&lt;/h1&gt;

&lt;p&gt;Dynamic configuration is not straightforward in an SPA e.g, you want to toggle some features in some environments, feed API endpoints that SPA should use dynamically rather than at build time.&lt;/p&gt;

&lt;p&gt;This is so because SPAs are bundled and the bundle is referenced in landing page. Browser retrieves the bundled file from server and executes it which loads the SPA and starts its lifecycle. So the SPA execution is entirely on the client i.e. browser and it is not possible to inject configuration like we do on server or an application installed on desktop.&lt;/p&gt;

&lt;p&gt;This &lt;a href="https://medium.com/angular-in-depth/handling-angular-environments-in-continuous-delivery-eeaee96f0aae"&gt;article&lt;/a&gt; explains the problem and possible solutions in the context of Angular.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Key takeaway is that running highly configurable software can also be a challenge: configurability can become a liability instead of an asset. Managing configuration should also be a criteria during design and development.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>Exception Handling in Different Types of Applications</title>
      <dc:creator>Pathik Desai</dc:creator>
      <pubDate>Fri, 24 Jul 2020 11:25:00 +0000</pubDate>
      <link>https://dev.to/pathiknd/exception-handling-in-different-types-of-applications-38eo</link>
      <guid>https://dev.to/pathiknd/exception-handling-in-different-types-of-applications-38eo</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Exception handling is common to most programming languages and the mechanisms and behaviours are similar in most languages: try\catch\finally. It is well documented. We are not going to discuss that.&lt;/p&gt;

&lt;p&gt;However, different approach to exception handling is required in different types of applications like a Library, a UI application, a Framework, etc., and that is the focus of this post. We'll see how exception handling needs to change depending on the nature of the application.&lt;/p&gt;

&lt;p&gt;Let's start with some fundamentals.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is an exception?
&lt;/h1&gt;

&lt;p&gt;Exception is an event during the execution of a program that disrupts the normal flow and prevents the program from doing what it is expected to do e.g., a program tries to write to a log file but the file cannot be opened.&lt;/p&gt;

&lt;p&gt;In such error conditions, runtime looks for handlers (try-catch) that are registered to handle such excceptions and when a handler is found, it is invoked with an Exception object having information about the event. The following diagram shows the normal flow of the program (Runtime &amp;gt; main &amp;gt; Method1 &amp;gt; Method2) and the flow when an exception occurs in Method2.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8oi293pesc6lxqcg91uy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8oi293pesc6lxqcg91uy.png" alt="Program Flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When an exception is not handled by a program, it reaches the runtime where it will be considered an unhandled exception which may result in a crash.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Two Pass vs One Pass&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;.Net Runtime has Two Pass exception handling implementation. Two Pass means the runtime first traverses through entire call stack to find a handler, and after either finding a handler or determining that it is an unhandled exception, it runs all the &lt;em&gt;finally&lt;/em&gt; blocks in the call stack.&lt;/p&gt;

&lt;p&gt;JVM on the other hand runs finally block in a method if a handler is not found in that method and then it moves up the call stack.&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://devblogs.microsoft.com/dotnet/the-good-and-the-bad-of-exception-filters/" rel="noopener noreferrer"&gt;CLR Exception Handling&lt;/a&gt; and &lt;a href="https://www.infoworld.com/article/2076868/how-the-java-virtual-machine-handles-exceptions.html" rel="noopener noreferrer"&gt;JVM Exception Handling&lt;/a&gt; for detailed explanation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Asynchronous Execution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Exception handling in asynchronous execution is important to understand. Let's see with an example.&lt;/p&gt;

&lt;p&gt;The following is a Java code that runs a method on new thread and exits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AsyncRun&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// TODO Auto-generated method stub&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AsyncRun.run on thread "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArithmeticException&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;    
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AsyncRun&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"main on thread "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NullPointerException&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" handled"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would be the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main on thread 1
AsyncRun.run on thread 15
java.lang.NullPointerException handled
Exception in thread "Thread-0" java.lang.ArithmeticException
        at exceptionhandling.AsyncRun.run(AsyncRun.java:13)
        at java.base/java.lang.Thread.run(Thread.java:835)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;NullPointerException&lt;/em&gt; thrown by the &lt;em&gt;main&lt;/em&gt; method is handled by the try-catch in &lt;em&gt;main&lt;/em&gt;, but the exception in &lt;em&gt;AsyncRun.run&lt;/em&gt; method is treated as an unhandled exception because JVM could not find a handler in the call stack on the thread running &lt;em&gt;AsyncRun.run&lt;/em&gt;. &lt;em&gt;AsyncRun.run&lt;/em&gt; is the first method to be called on the thread so the call stack ends there, the try-catch in the &lt;em&gt;main&lt;/em&gt; method won't apply to &lt;em&gt;AsyncRun.run&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;However, unlike main thread, unhandled exception on a separate thread did not result in a crash. .Net has same behaviour as Java for asynchronous execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alternative to Exceptions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Alternative to Exceptions is error handling, but for that program has to validate all scenarios and return different error codes e.g., a function writing to log files would have to first check if file exists and then return an error code if it doesn't, and the calling function needs to check the return value to see if the call was successful or not. This can be very unproductive and error prone.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why handle exceptions?
&lt;/h1&gt;

&lt;p&gt;Exception handling is required primarily for the following reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Prevent crashes&lt;/strong&gt;: Unhandled exception may result in application crash. So even to prevent a crash an application needs to handle exceptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alternate flow&lt;/strong&gt;: In some cases, there may be a need to change the flow of the program in the event of an error condition e.g., in online shopping portal, when a payment API request throws exception, user journey would require the application to handle it and take the user back to the basket page so that user can initiate the payment again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logging&lt;/strong&gt;: This is required for troubleshooting.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Where to handle exceptions?
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Where&lt;/strong&gt; to handle exception is very important and broadly there are two types of places where exceptions should be handled:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;All &lt;strong&gt;Entry Points&lt;/strong&gt; in to the program \ application to prevent crashes. As we have seen above when an exception reaches the runtime or framework, it may cause a crash. Entry Points can be one or more like:

&lt;ol&gt;
&lt;li&gt;main method&lt;/li&gt;
&lt;li&gt;Event handlers in a UI application - SPA or desktop application&lt;/li&gt;
&lt;li&gt;Public methods on a Controller in MVC&lt;/li&gt;
&lt;li&gt;Starting method of a background thread&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;To support different flows in the event of an error, exception handling is required where such diversions need to be implemented.&lt;/li&gt;

&lt;/ol&gt;

&lt;h1&gt;
  
  
  Exception Handling by Application Types
&lt;/h1&gt;

&lt;p&gt;Now let's try to see how all this applies for different application types:&lt;/p&gt;

&lt;h2&gt;
  
  
  Library
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A library is a set of functions / classes focusing on some problem domain. &lt;/li&gt;
&lt;li&gt;Libraries do not control the flow of program. Functions of libraries are called by the main program with some input and they return some output or provide some behaviour e.g, &lt;em&gt;RecommendationEngine&lt;/em&gt; executable uses libraries for logging, data access, etc. to perform its job but the flow of program is controlled by the executable only.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fybnygguydf3mvn87t9uw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fybnygguydf3mvn87t9uw.png" alt="Library"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Responsibility to prevent a crash or implement an alternate flow lies with the main program. &lt;/li&gt;
&lt;li&gt;&lt;p&gt;Therefore, code in a library &lt;em&gt;should not suppress exceptions&lt;/em&gt; because that would prevent the calling application from fulfilling alternate flow and logging requirements - it can catch exceptions and rethrow or provide expected output by catching exceptions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There can be scenarios where a library needs to handle exceptions like in the following case, but it should not suppress the exceptions. E.g., continuing with the above example, let's say the data can come from MySQL or MongoDB so DataAccess library itself relies on other libraries. But to make &lt;em&gt;RecommendataionEngine&lt;/em&gt; depend only on the &lt;em&gt;DataAccess&lt;/em&gt; library, the &lt;em&gt;DataAccess&lt;/em&gt; library can handle exception from &lt;em&gt;MySQL&lt;/em&gt; and &lt;em&gt;MongoDB&lt;/em&gt; and then throw its own exception. Re-throwing would ensure that &lt;em&gt;RecommendationEngine&lt;/em&gt; gets a chance to decide what to do with the exception.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8j60m0e5v374msxo3r8a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8j60m0e5v374msxo3r8a.png" alt="Library Dependency"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  API
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;APIs can be thought of as a library of functions exposed over a network e.g., continuing earlier example, if there is a decision to expose Data Access APIs as REST APIs, it would look like the following.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2f3ydxe759a1xrji50xo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2f3ydxe759a1xrji50xo.png" alt="API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As in the case of Library, the caller of API (RecommendationEgine) should handle the exception, but because of the change in nature of invocation of Data Access APIs, exceptions need to be handled for the following reasons:

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Data Access API as Library&lt;/em&gt;: in this case, when an exception occurs, the caller (RecommendationEngine) is in same process and the runtime lets it handle the exception - also the exception object would provide details about what happened so that caller can take appropriate action.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Data Access API as REST API&lt;/em&gt;: here the caller (RecommendationEngine) is not in the same process. Caller is expecting a valid HTTP response from the REST API. So if the API itself doesn't handle exception, the framework (ASP.Net MVC, Spring MVC, etc.) has to handle it and return a valid HTTP response, which may not provide enough details to the caller about the error.&lt;/li&gt;
&lt;li&gt;So REST API itself should handle the exception and return a response that the caller can use to determine that there was an error. In this case, the response (API Response Body) will have to carry error codes and caller should perform actions based on error codes.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  UI Application
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Almost all UI applications are written using some framework with the framework calling the application when there is some event. This makes the event handlers an entry point in to the application so exceptions should be caught on event handlers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Additional exception handling in a UI application will vary based on what the application is doing e.g, if the application is doing work on background threads, the entry points \ starting methods of the thread should handle exceptions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Framework
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Framework is an implementation of Inversion of Control pattern. Framework discovers, loads and calls its plug-ins on events a plug-in is interested in. Both the framework and the plug-ins communicate with each other using known public interfaces e.g,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpgmwthkwqrr82i0qh152.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpgmwthkwqrr82i0qh152.png" alt="Framework Structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This is how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(a) Spring (framework) &lt;strong&gt;discovers&lt;/strong&gt; controllers with &lt;em&gt;@Controller&lt;/em&gt; annotation on a Class&lt;/li&gt;
&lt;li&gt;(b) DI container would &lt;strong&gt;initialize&lt;/strong&gt;  the classes (or load plug-in) by calling their constructors&lt;/li&gt;
&lt;li&gt;(c) when a HTTP request for a matching URL is received, Spring MVC calls appropriate method on the plugin (Controller instance created in (b)) and returns the response.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;In the above diagram the calls from Spring to the application - marked with &lt;strong&gt;X&lt;/strong&gt; - are vulnerable points as Spring cannot assume that the application would not throw exceptions, so it would handle exceptions e.g., if &lt;em&gt;UserController.create&lt;/em&gt; method throws exception, Spring MVC would handle it and trigger alternate flow to return an appropriate HTTP response indicating error.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;So a framework must handle exception in all the places where it is invoking methods on its plug-in. &lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Framework itself cannot be the reason for a crash so it must make sure that it internally doesn't allow any exception to go unhandled and reach the runtime because that may result in a crash.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Any application should not let exceptions go unhandled with the exception of Libraries. At the minimum, all exceptions should be handled at the entry points in to the application. &lt;/p&gt;

</description>
      <category>java</category>
      <category>csharp</category>
      <category>webdev</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Generics Implementation of Java and C#</title>
      <dc:creator>Pathik Desai</dc:creator>
      <pubDate>Tue, 23 Jun 2020 05:29:04 +0000</pubDate>
      <link>https://dev.to/pathiknd/generics-implementation-of-java-and-c-31b4</link>
      <guid>https://dev.to/pathiknd/generics-implementation-of-java-and-c-31b4</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Generics are very powerful and commonly used in both Java and C# programming - especially in frameworks and libraries. &lt;/p&gt;

&lt;p&gt;Generics primarily provide type safety and improved performance by avoiding the need to cast variables.&lt;/p&gt;

&lt;p&gt;If you have been using C# generics and then use generics in Java - or vice versa, you will notice that both Java and C# generics look very similar. But they are very different in terms of how they are implemented and as a result what capabilities they have. We'll see that in the rest of this post.&lt;/p&gt;

&lt;h1&gt;
  
  
  Generics Implementation
&lt;/h1&gt;

&lt;p&gt;Generics support in a language is required at both &lt;strong&gt;compile time&lt;/strong&gt; and &lt;strong&gt;run time&lt;/strong&gt;. Let's use an example to understand this better.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A library &lt;em&gt;common-lib&lt;/em&gt; declares a generic type as shown below. This library is built and published which is then used in other programs.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GenericTest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;_ref&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;An application named &lt;em&gt;demo-app&lt;/em&gt; uses &lt;em&gt;common-lib&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="nc"&gt;GenericTest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyClass&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GenericTest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyClass&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;GenericTest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SomeClass&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GenericTest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SomeClass&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;//s = t; //allowed? type safety?&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;common-lib&lt;/em&gt; and &lt;em&gt;demo-app&lt;/em&gt; are physically different artifacts. When &lt;em&gt;demo-app&lt;/em&gt; is compiled, the compiler needs to know that GenericTest&amp;lt;T&amp;gt; is a generic type so it should be treated differently. Therefore when &lt;em&gt;common-lib&lt;/em&gt; is compiled, the compiled output should have information about the generic type. This will allow compiler to ensure type safety in &lt;em&gt;demo-app&lt;/em&gt; at compile time - both Java and C# guarantee compile time type safety.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reflection is supported by both Java and C#. Reflection APIs allow accessing type information at run time and create new objects, call methods on an object, etc. at run time. To support all these operations on generic types, generics support is required at run time also.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Java Generic Code Lifecycle
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Compilation
&lt;/h2&gt;

&lt;p&gt;Java uses the concept of &lt;a href="https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html" rel="noopener noreferrer"&gt;Type Erasure&lt;/a&gt; to support Generics in Java. Through Type Erasure, Java compiler converts all Generic type references to non-generic types at the time of compilation. Type Erasure approach was used to provide backward compatibility so that non-generic types can be passed to newer code written using generics.&lt;/p&gt;

&lt;p&gt;Let's understand with an example. The following is a simple generic class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GenericTest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;_ref&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T1&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Comparable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isEqual&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;T1&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compareTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_ref&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When this class is compiled, the generic type parameters are removed and replaced with non-generic equivalents. Following is the generated byte code - shown by &lt;a href="https://github.com/Konloch/bytecode-viewer" rel="noopener noreferrer"&gt;Bytecode Viewer&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu6701lkr8u13mowjfhvu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu6701lkr8u13mowjfhvu.png" alt="Java Byte Code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See the difference between source code and the compiled version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;//source code&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GenericTest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;//compiled code - GenericTest&amp;lt;T&amp;gt; became just GenericTest&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;generics&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nc"&gt;GenericTest&lt;/span&gt;

&lt;span class="c1"&gt;//source code&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;_ref&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//compiled code - T was replaced with Object&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;_ref&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;//source code&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T1&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Comparable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isEqual&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;T1&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//compiled code - T1 became Comparable because&lt;/span&gt;
&lt;span class="c1"&gt;//of constraint that T1 should be subtype of Comparable&amp;lt;T&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;isEqual&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Comparable&lt;/span&gt; &lt;span class="n"&gt;arg0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compiled Java code does not have any trace of generic types. Everything is mapped to a raw Java type.&lt;/p&gt;

&lt;p&gt;One of the side effects of Type Erasure is that &lt;em&gt;GenericTest&amp;lt;T&amp;gt;&lt;/em&gt; and &lt;em&gt;GenericTest&lt;/em&gt; are same after Type Erasure by the compiler, so it is not possible to have both in same package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Runtime
&lt;/h2&gt;

&lt;p&gt;At JVM level, there are no generic types. As explained in the earlier section, Java compiler removes all traces of generic types so the JVM doesn't have to do anything different to handle generic types.&lt;/p&gt;

&lt;h1&gt;
  
  
  C# Generic Code Lifecycle
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Compilation
&lt;/h2&gt;

&lt;p&gt;Following is the equivalent C# code of the above example in Java:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GenericTest&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;_ref&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;IsEqual&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IComparable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CompareTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the above code is compiled, the C# compiler retains the generic type information, which is used by the .Net Runtime to support generics.&lt;/p&gt;

&lt;p&gt;A peek in to compiled library using &lt;a href="https://docs.microsoft.com/en-us/dotnet/framework/tools/ildasm-exe-il-disassembler" rel="noopener noreferrer"&gt;IL Disassembler&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F63thepdrb9p58pfez5jg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F63thepdrb9p58pfez5jg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;IL Code of &lt;em&gt;IsEqual&lt;/em&gt; method (same as byte code of Java) - see underlined sections:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxeg2t5akrp6janwyd7ql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxeg2t5akrp6janwyd7ql.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Runtime
&lt;/h2&gt;

&lt;p&gt;.Net Runtime (CLR) uses the generic type information in the compiled code to create concrete types at runtime. Let's understand with an example.&lt;/p&gt;

&lt;p&gt;Following code creates three objects of GenericTest&amp;lt;T&amp;gt; for three different types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;GenericTest&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;intObj&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;GenericTest&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;GenericTest&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;doubleObj&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;GenericTest&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;GenericTest&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;strObj&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;GenericTest&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When this code is run, the .Net Runtime would create three concrete types dynamically based on the original GenericTest&amp;lt;T&amp;gt; generic type definition:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;GenericTest&amp;lt;int&amp;gt;&lt;/strong&gt;: T replaced with &lt;em&gt;int&lt;/em&gt;. This type will be used to create all new objects of type GenericTest&amp;lt;int&amp;gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GenericTest&amp;lt;double&amp;gt;&lt;/strong&gt;: T replaced with &lt;em&gt;double&lt;/em&gt;. This type will be used to create all new objects of type GenericTest&amp;lt;double&amp;gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GenericTest&amp;lt;Object&amp;gt;&lt;/strong&gt;: T replaced with &lt;em&gt;System.Object&lt;/em&gt;. This type will be used to create all new objects of any reference type like GenericTest&amp;lt;String&amp;gt;, GenericTest&amp;lt;FileStream&amp;gt;, GenericTest&amp;lt;SomeClass&amp;gt;, etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;.Net Runtime creates a new type for each primitive \ value type, which gives both type safety and performance benefit by avoiding boxing operations. &lt;/p&gt;

&lt;p&gt;For reference type, there is only type and the .Net Runtime type safety mechanism ensures type safety.&lt;/p&gt;

&lt;h1&gt;
  
  
  What's the impact?
&lt;/h1&gt;

&lt;p&gt;Due to the nature of implementation, there are few areas of differences between Java and C#:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primitive Types support

&lt;ul&gt;
&lt;li&gt;Java generics do not support primitive types - because Type Erasure cannot work in that case. &lt;/li&gt;
&lt;li&gt;C# supports primitive types (or Value Types in C#) in generics which gives two benefits &lt;strong&gt;(a)&lt;/strong&gt; type safety and &lt;strong&gt;(b)&lt;/strong&gt; performance benefits by removing boxing and unboxing needs - this is achieved by .Net Runtime's dynamic concrete type creation.&lt;/li&gt;
&lt;li&gt;There is an open item &lt;a href="https://bugs.openjdk.java.net/browse/JDK-8046267" rel="noopener noreferrer"&gt;JEP 218: Generics over Primitive Types
&lt;/a&gt; to support primitive types in Java generics&lt;/li&gt;
&lt;li&gt;An outcome of the above limitation in Java are number of Functional Interfaces like IntFunction, LongFunction, etc. If primitive types can be supported by generics, only one interface can be enough:
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="no"&gt;R&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;R&lt;/span&gt; &lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Type Erasure inserts casts wherever required to ensure type safety, but this will add to performance cost rather than improving performance by avoiding casts with Generics. E.g.,
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyClass&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;al&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyClass&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;al&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="c1"&gt;//Compiler would add cast&lt;/span&gt;
    &lt;span class="nc"&gt;MyClass&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;al&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//source&lt;/span&gt;
    &lt;span class="c1"&gt;//MyClass m = (MyClass)al.get(0) //compiled&lt;/span&gt;
    &lt;span class="c1"&gt;//this will be fine as al.get(0) anyway returns Object.&lt;/span&gt;
    &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;al&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run time operations - If you have to do runtime type checks on T (T instance of IEnumerable), reflect on generic types, or do &lt;em&gt;new T()&lt;/em&gt; kind of operations, it is either not possible in Java or you have to use workarounds. Let's see an example.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's write a function that deserializes Json string to an object using generic parameters.&lt;/p&gt;

&lt;p&gt;Following is the C# code for the same that would work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;getObject&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;JsonConvert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DeserializeObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// usage&lt;/span&gt;
&lt;span class="c1"&gt;// MyClass m = getObject&amp;lt;MyClass&amp;gt;("json string");&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But same thing can't work in Java as T.class would not compile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;getObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make the above code work, getObject method has to receive the Type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;getObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;//usage&lt;/span&gt;
&lt;span class="c1"&gt;// MyClass m = getObject&amp;lt;MyClass&amp;gt;("json string", MyClass.class);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;In the end, both Java and C# provide compile time type safety using different approaches. Due to support at runtime level, C# is able to provide performance benefits and more run time operations support. &lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.informit.com/articles/article.aspx?p=605369&amp;amp;seqNum=5" rel="noopener noreferrer"&gt;C# Generics Internals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you want to go to memory level details, read &lt;a href="https://alexandrnikitin.github.io/blog/dotnet-generics-under-the-hood/" rel="noopener noreferrer"&gt;.Net Generics under the hood&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Very detailed comparison of features - &lt;a href="http://www.jprl.com/Blog/archive/development/2007/Aug-31.html" rel="noopener noreferrer"&gt;Comparing Java and C# Generics - Jonathan Pryor's web log&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.in/Core-Java-SE-9-Impatient/dp/0134694724" rel="noopener noreferrer"&gt;Core Java SE 9 for the Impatient&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Software Security Overview</title>
      <dc:creator>Pathik Desai</dc:creator>
      <pubDate>Sat, 16 May 2020 12:32:12 +0000</pubDate>
      <link>https://dev.to/pathiknd/software-security-overview-3ldi</link>
      <guid>https://dev.to/pathiknd/software-security-overview-3ldi</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;As a developer, when you think of security, what comes to your mind? Is it clear what are different aspects that need to be handled to make your software secure? And why you need to do that?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Objective of this post is to provide that view and articulate what controls should be in place and how&lt;/em&gt;. Details of how to apply those controls would require separate posts and are not covered here - and lot of content is available on the web. &lt;/p&gt;

&lt;h1&gt;
  
  
  What is Software Security?
&lt;/h1&gt;

&lt;p&gt;Security implementation of a software application can be classified in two parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pre-deployment - building a secure software&lt;/li&gt;
&lt;li&gt;Post-deployment - security of the environment where software is running&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Software Security is pre-deployment. It is the process of identifying risks and building controls (or &lt;em&gt;Countermeasures&lt;/em&gt; as it is called in security terminology) in the software itself while it is being built. &lt;/p&gt;

&lt;p&gt;Software Security is the focus of this post. We will see controls commonly used and what risks they mitigate.&lt;/p&gt;

&lt;p&gt;For more details on the topic, see &lt;a href="https://www.synopsys.com/blogs/software-security/software-security/" rel="noopener noreferrer"&gt;What is Software Security&lt;/a&gt; by &lt;a href="https://www.garymcgraw.com/" rel="noopener noreferrer"&gt;Gary McGrow&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Nature of security
&lt;/h1&gt;

&lt;p&gt;A software application would generally have two aspects:&lt;/p&gt;

&lt;p&gt;a. Services that provide some functionality&lt;br&gt;
a. Data generated and consumed by the services&lt;/p&gt;

&lt;p&gt;Security can be defined as &lt;em&gt;defending services and data from unauthorized and malicious usage at all times&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Defending&lt;/em&gt; is the key word here. Defense literally means &lt;em&gt;an act of resisting an attack&lt;/em&gt;. That means attacks can happen anytime and any number of times, and we need to keep protecting the system from these attacks. &lt;/p&gt;

&lt;p&gt;That's what makes security of a software application very difficult because to it is not easy to to get it right all the time. &lt;/p&gt;

&lt;p&gt;Also, there is no room for error. One incident may be enough to destroy the reputation and business built over the years.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to approach security?
&lt;/h1&gt;

&lt;p&gt;The following is the minimum that should be done:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Follow industry best practices rather than inventing our own mechanisms. These best practices have come out of years of learning and it is better to rely on that tried and tested knowledge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secure by design: make security a criteria in all aspects like Requirements, Architecture, DevOps, Engineering Practices like code reviews, unit testing, application testing, etc. This would ensure that everything is built secure by default - security is not thought of after delivering the functionality which happens on many projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  What would make a software secure?
&lt;/h1&gt;

&lt;p&gt;CIA triad (or AIC triad) is commonly used for Information Security, but it also helps to better understand security in general. A software should have the following properties to be secure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Confidentiality&lt;/strong&gt;: Authorized access to services and data e.g., to view your GMail mailbox and send emails, you must successfully login to GMail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integrity&lt;/strong&gt;: Integrity and authenticity of data presented (in transit) and stored (at rest) e.g., the emails shown by GMail are exactly how they were sent by the sender and content is same as that stored on GMail servers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Availability&lt;/strong&gt;: Software is always available to all authorized users for all legitimate use-cases e.g., GMail services are always available to its users.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Design Principles
&lt;/h1&gt;

&lt;p&gt;See &lt;a href="https://github.com/OWASP/DevGuide/blob/master/02-Design/01-Principles%20of%20Security%20Engineering.md" rel="noopener noreferrer"&gt;Secure Design Principles&lt;/a&gt; by OWASP for details. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Defense in depth&lt;/strong&gt; is a very important principle to follow while designing the software. In simple terms, it means to have controls at different layers. It will ensure breach at one layer will not result in failure. We'll see some examples later in the post.&lt;/p&gt;

&lt;h1&gt;
  
  
  Controls
&lt;/h1&gt;

&lt;p&gt;The following are the controls that are commonly used. A combination of these controls can be implemented depending on the risk.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu4yu0adxbda77beahhvm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu4yu0adxbda77beahhvm.png" alt="Software Security Controls"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;These are commonly used controls. This is not an exhaustive list e.g., though it is not included above, applying signatures on every request and response can be used if the risk is high and require that level of security.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We will look at each of these. However, they build on the security building blocks like authentication, cryptography, certificates, etc. If you are not familiar with these concepts, recommend to go through &lt;a href="https://dev.to/pathiknd/software-security-building-blocks-26g1"&gt;Software Security Building Blocks&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Authentication
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Authentication is required to perform authorization. Authentication will establish the identity of the entity trying to access the software, and based on that authorization can be applied.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There can be two types of authentication:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Authenticating an end user&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;OAuth2&lt;/em&gt; and &lt;em&gt;OpenID Connect&lt;/em&gt; are widely used protocols for this. &lt;/li&gt;
&lt;li&gt;There are number of identity management services that support these protocols. &lt;/li&gt;
&lt;li&gt;Using standard protocol rather than custom authentication mechanism would make integrations with other systems easier.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Authenticating a client&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two commonly used methods to authenticate a Client (a program calling an API):

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;OAuth2 - Client Credentials Grant&lt;/em&gt;: This is an OAuth2 workflow that allows a client to authenticate itself using a &lt;em&gt;client-id&lt;/em&gt; and a &lt;em&gt;client-secret&lt;/em&gt; and acquire a token which it can then use to call APIs.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;TLS Mutual Authentication&lt;/em&gt;: both Client and the Server trust each other's X.509 certificates used to establish TLS connection. Connection is established only if trusted parties try to connect. This is suitable in server-to-server communications e.g., when you call external APIs from your backend.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;For Web Applications that rely on cookie based session tracking, authenticating legitimate requests from client (Browser) is required to avoid Cross Site Request Forgery (CSRF). Watch this &lt;a href="https://www.youtube.com/watch?v=9inczw6qtpY&amp;amp;feature=youtu.be" rel="noopener noreferrer"&gt;video&lt;/a&gt; to see a demo.&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ol&gt;

&lt;h1&gt;
  
  
  Authorization - for Confidentiality
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Authorization in this context is required for the following objective:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authenticated entity - a user or a client - can access only the data that they are supposed to access

&lt;ul&gt;
&lt;li&gt;When you login to GMail, GMail does not show someone else's emails to you.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All read operations on data associated with a user should have the following checks:

&lt;ol&gt;
&lt;li&gt;The logged-in user is same as the user associated with data e.g., User Id on a payment transaction record must match the User Id of logged in user. The same check can be applied to clients if required.&lt;/li&gt;
&lt;li&gt;If 1 is not true, the logged-in user has privileges to access other user's data.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Authorization - for Integrity
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Authorization in this context is required for the following objective:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authenticated entity - a user or a client - can perform only those data manipulation actions that they are authorized to.

&lt;ul&gt;
&lt;li&gt;When you login to Outlook, you cannot manage someone else's calendar unless the other person has given you permissions to manage his or her calendar.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;All operations should have the following check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the logged-in user authorized to perform the operation?

&lt;ul&gt;
&lt;li&gt;If Role Based Access Control (RBAC) is used, is a role required to perform this operation assigned to the logged-in user? Spring Security and .Net Framework easily allow such access control using declarative methods - annotations \ attributes.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;The logged-in user is same as the user associated with data that is being modified e.g., User Id on a payment transaction request must match the User Id of the logged in user.&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Client Authorization&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you have APIs that can be consumed by multiple clients, authorizing clients is also important e.g., in a Microservice architecture, API gateway can block requests if client is not authorized to use an API&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwjrxtflnuvel90p70szm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwjrxtflnuvel90p70szm.png" alt="Client Authorization"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An admin can disable a user so it should be allowed from Admin Portal client only. If you use OAuth2, the tokens carry Client information and this can be done easily.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The same check should also be applied on the microservice - remember Defense in depth? In case someone mistakenly removes check on API Gateway, microservice will still block the client.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Data Privacy
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Personally Identifiable Information (PII) is any data that can identify an individual e.g., Mobile Number, Email address, etc. Unauthorized access to such information can be a breach of privacy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify PIIs captured by the software.&lt;/li&gt;
&lt;li&gt;Do not display PIIs without masking e.g., mobile number as 98XXX XXX76.&lt;/li&gt;
&lt;li&gt;All communications like email, SMS, etc. should mask PIIs.&lt;/li&gt;
&lt;li&gt;Do not write PIIs to the log files in plain text.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Input Validation
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Accepting invalid input can compromise the integrity of the data e.g., accepting a past date on payment transaction request would result in incorrect state of the system.&lt;/p&gt;

&lt;p&gt;Lack of input validation can pose a vulnerability for Cross Site Scripting (XSS) attacks. Watch this &lt;a href="https://www.veracode.com/security/xss" rel="noopener noreferrer"&gt;video&lt;/a&gt; for quick intro to XSS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inputs should be validated at all layers - remember Defense in depth!&lt;/li&gt;
&lt;li&gt;Sanitize all text input to remove &amp;lt;script&amp;gt; tags. Otherwise the same text might end-up in a malicious script being executed when it is displayed on the browser - that's XSS in nutshell.&lt;/li&gt;
&lt;li&gt;If a file is being uploaded as part of some functionality, it should also be treated as an input and be validated - scanned and format validated if required.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  TLS \ HTTPS
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Security of data when it is in transit. It protects against &lt;a href="https://www.veracode.com/security/man-middle-attack" rel="noopener noreferrer"&gt;Man-in-the-middle&lt;/a&gt; attack which can compromise both integrity and confidentiality of the system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always use TLS 1.2 (currently latest) and HTTPS for all internet traffic.&lt;/li&gt;
&lt;li&gt;In mobile applications, implement &lt;em&gt;SSL Pinning&lt;/em&gt; to make sure the mobile app always talks to "your" server only. See &lt;a href="https://medium.com/@appmattus/android-security-ssl-pinning-1db8acb6621e" rel="noopener noreferrer"&gt;Android Security: SSL Pinning&lt;/a&gt; for details.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Encryption and Hashing
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Security of data at rest (when stored) is as important as security in transit. Storing encrypted or hashed data will protect unauthorized access to data at rest. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify data that needs to be stored encrypted or hashed. Hash of a password is stored so it is irreversible even with the keys.&lt;/li&gt;
&lt;li&gt;Encryption key and the data should not be stored together e.g., in same database.&lt;/li&gt;
&lt;li&gt;Challenges

&lt;ul&gt;
&lt;li&gt;Encrypted data is as secure as the key it is encrypted with. Therefore, management of encryption key is very important when encrypting data at rest. &lt;/li&gt;
&lt;li&gt;Performance trade-off

&lt;ul&gt;
&lt;li&gt;having to decrypt data on all read operations will impact the overall responsiveness of the system if frequently used data fields are stored encrypted.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Key rotation is challenge

&lt;ul&gt;
&lt;li&gt;Once data is stored with an encryption key, it has to be decrypted with the same key. &lt;/li&gt;
&lt;li&gt;When data starts accumulating over the years, rotating the encryption key becomes a challenge because existing data needs to either (a) be re-encrypted with new key, which may be challenging in a live system or (b) handle multiple keys and key-data mapping in program itself, which can also become very complicated.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  Auditing and Logging
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Auditing helps to track the change in state and who caused that change e.g., if a user's name was updated, audit records will capture when it was updated and who updated it. This can be useful in event of an incident.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logging also helps to trace errors and troubleshoot issues.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auditing is straightforward. Hibernate makes it very easy in Java.&lt;/li&gt;
&lt;li&gt;Logging to is straightforward, but in distributed architecture using &lt;a href="https://www.elastic.co/what-is/elk-stack" rel="noopener noreferrer"&gt;ELK Stack&lt;/a&gt; or something similar is important to see all logs in one place.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Secrets Management
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Secrets are database password, API access credentials, encryption key, etc.&lt;/li&gt;
&lt;li&gt;Most of these are configurations but if they are left in plain text, it poses risk as they can be misused.

&lt;ul&gt;
&lt;li&gt;Let's say you use an external SMS service provider to send SMS. If the API access credentials for this external service are not protected, there is a risk of someone being able to send SMS on behalf of you.&lt;/li&gt;
&lt;li&gt;Comprised encryption key is even bigger risk.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can use AWS Secrets Manager, Vault, etc. to store such secrets.&lt;/li&gt;
&lt;li&gt;Alternative is

&lt;ol&gt;
&lt;li&gt;Keep secrets encrypted in normal configuration - properties file or web.config.&lt;/li&gt;
&lt;li&gt;The encryption key is stored in AWS Secrets Manager, vault, etc.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;In a Single Page Application (SPA) and Mobile Application, a JWT token would be used to call APIs - token is passed in Authorization header with every request. Since it is a bearer token, anyone with the token can use the APIs. The token should not be stored on clients more than required&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: There is trade-off between security and usability. Most applications (web and mobile) keep users logged in forever, which means they have to keep a token with long validity on the client - in browser local storage or mobile. This is a risk. So a decision has to be made based on nature of the application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Sender Policy Framework
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's say your application sends emails from &lt;em&gt;&lt;a href="mailto:connect@myapp.co"&gt;connect@myapp.co&lt;/a&gt;&lt;/em&gt; address. If someone else is able to send emails using the same domain myapp.co, it can impact your reputation and business. This is called &lt;strong&gt;Spoofing&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Sender Policy Framework prevents such misuse of your domain and assures authenticity of emails.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is configured with a DNS entry. See &lt;a href="https://www.sparkpost.com/resources/email-explained/spf-sender-policy-framework/" rel="noopener noreferrer"&gt;What is SPF&lt;/a&gt; for details.&lt;/p&gt;

&lt;h1&gt;
  
  
  Resiliency
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Resiliency here means ability of the application to be responsive (operational) in the event of a failure. Read &lt;a href="https://www.reactivemanifesto.org/" rel="noopener noreferrer"&gt;Reactive Manifesto&lt;/a&gt; for detailed explanation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the context of security, we can loosely define resiliency to the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the event of a sudden increase in load (with malicious intent i.e. Denial of Service (DoS) attack), can the system remain operational?

&lt;ul&gt;
&lt;li&gt;All cloud providers have services that provide protection against DoS \ DDoS attacks, but these are reactive in nature and may take a little time to react. The application should be able to withstand that otherwise the protection is of no use.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;How quickly the application can recover in the event of a downtime?&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are different modern architecture patterns to achieve resiliency, but in any case - even monolith architecture, the system can be resilient with following implementation:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Elasticity&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elasticity means ability to scale up or down depending on the load.&lt;/li&gt;
&lt;li&gt;It is easy implement with Load Balancing and Auto Scaling in any cloud environment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Automation&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated builds and deployments is critical to quickly recover in the case of a failure.&lt;/li&gt;
&lt;li&gt;Unit testing and Test Automation would also help to do quick releases for urgent patches.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Configuration Simplicity&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configurations keep getting added to a software as it evolves and often it become very difficult to correctly configure the software.&lt;/li&gt;
&lt;li&gt;This is important to have quick recovery in case of a failure.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you have reached this far, you are patient and dedicated person! Thanks for reading :)&lt;/p&gt;

</description>
      <category>security</category>
    </item>
    <item>
      <title>Software Security Building Blocks</title>
      <dc:creator>Pathik Desai</dc:creator>
      <pubDate>Sat, 16 May 2020 08:04:30 +0000</pubDate>
      <link>https://dev.to/pathiknd/software-security-building-blocks-26g1</link>
      <guid>https://dev.to/pathiknd/software-security-building-blocks-26g1</guid>
      <description>&lt;p&gt;We'll cover the following building blocks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Secure communication&lt;/li&gt;
&lt;li&gt;Authorization&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Secure Communication
&lt;/h1&gt;

&lt;p&gt;TLS \ HTTPS is the means for secure communication between a service and a client. However, for TLS to work, the following are required:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cryptography&lt;/li&gt;
&lt;li&gt;Cryptographic Hash Function&lt;/li&gt;
&lt;li&gt;A way to exchange cryptographic keys - done using X.509 certificates&lt;/li&gt;
&lt;li&gt;Authenticating certificates&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once all these things are in place, TLS protocol can establish a secure communication channel. We'll go through these one by one.&lt;/p&gt;

&lt;h1&gt;
  
  
  Cryptography - Encryption &amp;amp; Decryption
&lt;/h1&gt;

&lt;p&gt;Cryptography is process of converting plain text in to unintelligible text and vice versa. Encryption converts plain text to unintelligible text and decryption does the revers of it.&lt;/p&gt;

&lt;p&gt;Cryptographic algorithms can be divided in to two types: Symmetric Key and Asymmetric Key. &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criteria&lt;/th&gt;
&lt;th&gt;Symmetric Key&lt;/th&gt;
&lt;th&gt;Asymmetric Key&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Keys&lt;/td&gt;
&lt;td&gt;Same key is used to encrypt and decrypt&lt;/td&gt;
&lt;td&gt;A key pair private key-public key is used. &lt;br&gt; Private key is not shared with anyone. Public key shared with everyone. &lt;br&gt; Data encrypted with private key can be decrypted ONLY with public key and vice versa&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Algorithms&lt;/td&gt;
&lt;td&gt;AES 256&lt;/td&gt;
&lt;td&gt;RSA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;See &lt;a href="https://howhttps.works/the-keys/"&gt;How Symmetric Key and Asymmetric Key cryptography works&lt;/a&gt; explained in very simple terms.&lt;/p&gt;

&lt;h1&gt;
  
  
  Hashing
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Hash functions are algorithms that take a text of any length and produce a fixed length text. The output is same as long as the input is same e.g., Input = "This is test" and Output of Hash function = "112345", it will always give this output for same input.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The reverse is not possible. "112345" cannot be converted to "This is test"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passwords are stored as hash values so that they can only be compared (hash of entered password = hash stored in database) but cannot be recovered by anyone.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SHA family of algorithms for hashing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  X.509 Certificate
&lt;/h1&gt;

&lt;p&gt;X.509 certificates are used to associate a public key to the entity that owns it - it can be an organization, a website, or an individual.&lt;/p&gt;

&lt;p&gt;Clicking on padlock in any browser shows the X.509 certificate associated with the domain. It has public key and many other information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4VXpLz2E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4fwsmq4dsepz0i2c1690.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4VXpLz2E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4fwsmq4dsepz0i2c1690.PNG" alt="X.509 in chrome" width="613" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Certificates are issued by Certificate Authorities (CA) who are trusted by browsers. In Chrome, Go to Settings &amp;gt; Privacy and Security &amp;gt; More &amp;gt; Manage Certificates, to see root and intermediate CAs trusted by the browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q8iXFEkp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ej9lwcalcikwmcceuwtb.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q8iXFEkp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ej9lwcalcikwmcceuwtb.PNG" alt="Trusted Roots" width="530" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Digital Signatures
&lt;/h1&gt;

&lt;p&gt;Digital Signatures ensure the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Integrity of message - message is as it was sent&lt;/li&gt;
&lt;li&gt;Authenticity of message - message has come from original source&lt;/li&gt;
&lt;li&gt;Non-repudiation - sender cannot deny sending the message&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Digital Signatures are not limited to internet but it is easy to understand it in the context of traffic on internet. This is how it will work:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IvR5iQlI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a1e04ik07hqkdv372bpf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IvR5iQlI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a1e04ik07hqkdv372bpf.png" alt="Digital Signature" width="601" height="894"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's see how the three objectives are met:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Integrity - if hash values match, message was not modified in transit&lt;/li&gt;
&lt;li&gt;Authenticity - signature decrypted with public key and hash values match, so the signature was generated with private key.&lt;/li&gt;
&lt;li&gt;Non-repudiation - if #1 and #2 are met, sender cannot deny sending it because otherwise both #1 and #2 would fail.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;X.509 certificates are signed by the CA and browser validate the signatures in similar way e.g., &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;SecureOne, Inc&lt;/em&gt; is a root CA and trusted in chrome. It has issued a X.509 certificate to &lt;em&gt;yourapp.co&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;when you open &lt;em&gt;yourapp.co&lt;/em&gt; in browser, browser gets X.509 certificate from &lt;em&gt;yourapp.co&lt;/em&gt; server.&lt;/li&gt;
&lt;li&gt;It tries to validate the certificate by validating its signature - it has public key of the root CA in its store.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;See &lt;a href="https://howhttps.works/certificate-authorities/"&gt;How the X.509 certificates are validated&lt;/a&gt; explained in very simple way.&lt;/p&gt;

&lt;h1&gt;
  
  
  Transport Layer Security (TLS)
&lt;/h1&gt;

&lt;p&gt;TLS builds on everything we discussed above. Its predecessor is SSL (Secure Socket Layer). TLS is meant for a secure connection at Layer 4 \ transport layer. &lt;/p&gt;

&lt;p&gt;HTTPS is HTTP on TLS. TLS 1.2 is the latest version supported by browsers.&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://howhttps.works/https-ssl-tls-differences/"&gt;TLS and HTTPS&lt;/a&gt; explained in simple terms.&lt;/p&gt;

&lt;p&gt;Whenever you open a website in browser, underneath a process happens called TLS Handshake which establishes a secure channel between browser and server. See &lt;a href="https://howhttps.works/the-handshake/"&gt;How certificates play a crucial role in securing traffic on internet&lt;/a&gt; for simple explanation of the handshake.&lt;/p&gt;

&lt;h1&gt;
  
  
  Authentication
&lt;/h1&gt;

&lt;p&gt;Authentication is the process of validating whether an entity is who it claims to be e.g., when you login to Gmail with &lt;a href="mailto:youremail@gmail.com"&gt;youremail@gmail.com&lt;/a&gt;, "&lt;a href="mailto:youremail@gmail.com"&gt;youremail@gmail.com&lt;/a&gt;" is the entity and Gmail validates that by matching the password you provide with what is stored in its database.&lt;/p&gt;

&lt;p&gt;Credentials are required to validate the identity. There are three types of credentials that are generally used:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What user &lt;strong&gt;knows&lt;/strong&gt; e.g., password&lt;/li&gt;
&lt;li&gt;What user &lt;strong&gt;possesses&lt;/strong&gt; e.g., OTP on mobile, link in email, etc.&lt;/li&gt;
&lt;li&gt;What user &lt;strong&gt;is&lt;/strong&gt; e.g., fingerprint&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When a combination of these types is used, it is called Two-Factor \ Multi-Factor Authentication. This is decided based on criticality and usability of application.&lt;/p&gt;

&lt;h1&gt;
  
  
  Authorization
&lt;/h1&gt;

&lt;p&gt;Once authenticated, authorization is the process of evaluating whether the authenticated identity can perform an action or not.&lt;/p&gt;

&lt;p&gt;For most applications, real need is Authorization but it is not possible without Authentication.&lt;/p&gt;

&lt;p&gt;Now that you have understood the basics, read &lt;a href="https://dev.to/pathiknd/software-security-overview-3ldi"&gt;Software Security Overview&lt;/a&gt; to get an overall view of building a secure software.&lt;/p&gt;

</description>
      <category>security</category>
    </item>
    <item>
      <title>Modularity in Java and .Net</title>
      <dc:creator>Pathik Desai</dc:creator>
      <pubDate>Thu, 14 May 2020 11:53:49 +0000</pubDate>
      <link>https://dev.to/pathiknd/modularity-in-java-and-net-3dnj</link>
      <guid>https://dev.to/pathiknd/modularity-in-java-and-net-3dnj</guid>
      <description>&lt;p&gt;We’ll explore modularity in Java and .Net platforms, but before let’s first spend a little time on understanding what and why of modularity.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is a Module?
&lt;/h1&gt;

&lt;p&gt;Dictionary say a module is &lt;em&gt;“one of a set of separate parts that, when combined, form a complete whole”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So a module needs to have two main characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide one or more related set of services via a standard interface — having standard interface would make a module reusable and replaceable&lt;/li&gt;
&lt;li&gt;Hide implementation details from the consumers of the services&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What is Modular thinking?
&lt;/h1&gt;

&lt;p&gt;Modular thinking would involve the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Break down the problem in small parts i.e. modules. Each part would satisfy the following:

&lt;ul&gt;
&lt;li&gt;Each module is focused on one or more related services \ functions&lt;/li&gt;
&lt;li&gt;Services are exposed using a standard interface&lt;/li&gt;
&lt;li&gt;Each module can potentially be used in any place where the same services are required&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Create the final solution by composing different modules together&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Almost everything around us is an example of modular thinking e.g. Automobiles, Personal Computer, Electronic Devices, etc.&lt;/p&gt;

&lt;p&gt;Most of today’s software are built using tools and platforms that are built in modular approach e.g., Spring Framework and .Net Framework, two very popular frameworks in Java and .Net, are both modular in nature. Both have number of modules (libraries) and those modules can be used (or reused!) in solutions for different problems.&lt;/p&gt;

&lt;h1&gt;
  
  
  But why Modularity?
&lt;/h1&gt;

&lt;p&gt;What do we gain from modular approach to the solution? I think the following three are the primary benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Reuse&lt;/em&gt; : Same module can be reused elsewhere, saving time and effort&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Stability&lt;/em&gt;: A change in the system is reduced to small area (implementation is hidden from consumers) and that allows more complete testing in shorter time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Parallel Execution&lt;/em&gt;: Multiple modules can be developed by different teams in parallel and final solution built by composing those modules. Saving time to market.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Logical &amp;amp; Physical Modules
&lt;/h1&gt;

&lt;p&gt;In software applications, logical grouping of functions and services is done to create a modular design. This would be an outcome of the application of Software Architecture principles on the problem domain e.g., the following modules may be identified for a Ticket Booking application, each focused on a specific area of the solution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nN3J7G2v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9jpbl8zjwbslgsdh0k9n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nN3J7G2v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9jpbl8zjwbslgsdh0k9n.png" alt="Logical Modules" width="361" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, that’s still a design of the software application. Working software (application binaries) they can be in one of the two forms shown below:&lt;/p&gt;

&lt;p&gt;a. an executable file containing all the modules. Here, the modules may internally be organized separately in the source tree of the application, but physically they all are in one executable file produced by building the application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--82pXY44p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/q4hi4lxvobu5y5v5pifw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--82pXY44p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/q4hi4lxvobu5y5v5pifw.png" alt="Single Executable" width="281" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;b. each module is a library and the application is using the libraries. Libraries are built and released separately from the main Application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MZPX1l7J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jnacugk7natm64i3jigc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MZPX1l7J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jnacugk7natm64i3jigc.png" alt="Modular Structure" width="361" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Option (b) is the modular approach that we all are familiar with and use everyday. Option (b) gives all the benefits of modularity listed above.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It is said that Unit of Release is the Unit of Reuse. There is no scope for reuse in Option (a).&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Required Platform Capabilities
&lt;/h1&gt;

&lt;p&gt;To support the modularity of option (b), a platform needs to have at least the following capabilities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Encapsulation&lt;/em&gt; : Encapsulation at module level. This is to ensure consumer uses only standard public interface and the details are hidden. Consumers cannot build dependency on “details” so that details can change without breaking anything e.g., in a logging library, &lt;em&gt;com.mylogger.api.Logger&lt;/em&gt; is public interface and &lt;em&gt;com.mylogger.service.impl.FileLogger&lt;/em&gt; is the class implementing logging to file. Users of logging library should not have access to &lt;em&gt;FileLogger&lt;/em&gt; so that &lt;em&gt;FileLogger&lt;/em&gt; can change without breaking any dependent application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Dependency Management&lt;/em&gt; : Since each module would also depend on some other module, there needs to be a way for each module to declare its dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Dependency Discovery&lt;/em&gt; : Once a module has declared its dependencies, the platform needs to discover those dependencies (modules i.e. libraries) at runtime, load them and make them available.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Versioning&lt;/em&gt; : Versioning of modules is required to let each module evolve independently without breaking other modules depending on it.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Comparison of Java and .Net platforms
&lt;/h1&gt;

&lt;p&gt;Let’s compare Java and .Net on these parameters&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tlV-wmxx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5u7mooh43pghv9tf7ffq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tlV-wmxx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5u7mooh43pghv9tf7ffq.PNG" alt="Alt Text" width="824" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;The package structure at runtime is used to locate .class files. JVM would look for exact same directory structure as the package name e.g. all types under “com.covidservice.api.service” should be found under “com/covidservice/api/service” on the Classpath JARs. So a package is not really treated as a dependency by JVM. JVM searches for .Class file when it has to create a new Class or Instance — this is different from how dependencies are managed in Java 9 and .Net.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;**&lt;em&gt;Java does not support versioning at JVM layer. The versions of JARs are maintained using naming convention i.e. including version in JAR filenames like spring-web-1.0.0-RELEASE.jar. If you have wrong version on Classpath or Modulepath, JVM would use that as long as the .Class file (Java 8) or Module (Java 9) are found.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  OSGi — Dynamic module system for Java
&lt;/h1&gt;

&lt;p&gt;OSGi is an industry alliance for &lt;em&gt;“a vendor-independent, standards-based approach to modularizing Java software applications and infrastructure”&lt;/em&gt;. OSGi was formed in late 1990s.&lt;/p&gt;

&lt;p&gt;There are many implementations of OSGi specifications like Apache Felix, Eclipise Equinox, etc.&lt;/p&gt;

&lt;p&gt;OSGi component system is used to build Eclipse IDE, JBoss, WebLogic, etc.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Modular architecture is a necessity once complexity and scope grows beyond certain point. It is difficult to introduce modularity at a later stage so better to do it from beginning.&lt;/p&gt;

&lt;p&gt;Modular design can be created by applying principles of Software Architecture, but platforms used to build the software need to support modular architecture. Java 9 and .Net are more capable than Java 8 — for reasons explained above — to enforce modularity&lt;/p&gt;

</description>
      <category>java</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
