<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title></title>
  <subtitle></subtitle>
  <id>https://www.endpointdev.com/blog/tags/software/</id>
  <link href="https://www.endpointdev.com/blog/tags/software/"/>
  <link href="https://www.endpointdev.com/blog/tags/software/" rel="self"/>
  <updated>2021-05-18T00:00:00+00:00</updated>
  <author>
    <name>End Point Dev</name>
  </author>
  
    <entry>
      <title>Choosing Between SaaS and a Custom Website</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2021/05/choosing-between-saas-and-custom-website/"/>
      <id>https://www.endpointdev.com/blog/2021/05/choosing-between-saas-and-custom-website/</id>
      <published>2021-05-18T00:00:00+00:00</published>
      <author>
        <name>Greg Hanson</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2021/05/choosing-between-saas-and-custom-website/drafting.jpg&#34; alt=&#34;&#34;&gt;
&lt;a href=&#34;https://unsplash.com/photos/-FPFq_trr2Y&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://unsplash.com/@d_mccullough&#34;&gt;Daniel McCullough&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So you need a website, but you’re not sure whether you want to pay for a website provided as software as a service (SaaS), or build a custom website and host it.&lt;/p&gt;
&lt;p&gt;The options are plentiful, as are the reasons for building a website in the first place. The purpose of this article is not to put forward specific packages or providers for consideration, rather I want to discuss how you might make that decision more objectively. Also, this discussion is for a commercial website, not a personal website or blog.&lt;/p&gt;
&lt;p&gt;Here at End Point, we receive many inquiries asking for new websites. We are well equipped to help you work through this process, and are happy to do so. But for those of you who want to “go it alone”, or if you just want to be better prepared before giving us a call, read on for some things to consider as you make a pros &amp;amp; ​cons list for SaaS vs. custom websites.&lt;/p&gt;
&lt;p&gt;While deciding between a SaaS offering and a custom build carries unlimited considerations, here are a few main points to help you narrow down the field.&lt;/p&gt;
&lt;h3 id=&#34;experience&#34;&gt;Experience&lt;/h3&gt;
&lt;p&gt;The foremost factor that you should consider for your pros &amp;amp; cons list is your experience. This may come as a little bit of a shock, as you might think that budget would be the top consideration. Budget is very important, but it is largely determined by your experience with your chosen technology. Don’t think for a minute that either SaaS or custom development cannot consume almost any budget, especially when you are working with an unfamiliar technology.&lt;/p&gt;
&lt;p&gt;So before budget, comes experience. Experience can be futher divided into experience with your business and experience with websites in general. Here are a few questions to start off with.&lt;/p&gt;
&lt;p&gt;In your industry, are you a:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Rookie&lt;/li&gt;
&lt;li&gt;Veteran&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;How long have you owned this business?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;1–3 years&lt;/li&gt;
&lt;li&gt;3+ years&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Does this business have an existing website?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;No&lt;/li&gt;
&lt;li&gt;Yes&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If yes, is it currently SaaS or custom-developed?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;SaaS&lt;/li&gt;
&lt;li&gt;Custom-developed&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you answered “1” to more than half of the above questions, it’s more likely that a SaaS system would be a better fit for you. If you mostly answered “2”, you may want to lean towards custom. These questions are not definitive, but are meant to help you decide where to focus your research.&lt;/p&gt;
&lt;h3 id=&#34;budget&#34;&gt;Budget&lt;/h3&gt;
&lt;p&gt;In general, if your budget is under $10,000 then SaaS is most likely the choice for you. Some exceptions here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You are a talented web programmer.&lt;/li&gt;
&lt;li&gt;Your brother, sister, friend, or cousin is a talented web programmer.&lt;/li&gt;
&lt;li&gt;You or your developer friend have enough time to devote to this endeavor. You will need a lot.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Custom websites are no longer appropriate for the average business owner with less than a $10k minimum start up cost, as well as a $1–3k monthly budget for ongoing improvements and maintenance. Currently, droves of talented programmers are working for SaaS companies, building tools for you to use to build your own website. In fact, SaaS offerings are so much cheaper and more widely supported that building a custom site for the average small business usually makes little sense.&lt;/p&gt;
&lt;p&gt;If your budget is $10k or more, you are probably capable of funding a custom website. However, this alone should not rule out a SaaS website. SaaS offerings come in many shapes and sizes, and many are fully capable of running enterprise-level websites!&lt;/p&gt;
&lt;h3 id=&#34;how-does-your-business-make-money&#34;&gt;How does your business make money?&lt;/h3&gt;
&lt;p&gt;One good case for using a custom website is if your company offers a niche product. Most SaaS offerings are based on popular business or product templates, so they might not fit well if you need to break from the mold.&lt;/p&gt;
&lt;p&gt;For example, do you sell clothing, movies, or tools? There are great SaaS offerings out there that can have your website up and running in less than a day. Do you provide a service that uses multiple providers, working in different capacities and for different rates depending on the level of service provided? You may need a custom application! The further from commonplace your products or services are, the more likely it is that you will need a custom application.&lt;/p&gt;
&lt;p&gt;Again, all of this advice is general, and there are exceptions to every rule. SaaS choices still require customizing to fit your business model. None of them will fit perfectly, and you will usually need to configure and add plugins to make your site conform to your business practices. SaaS offerings typically have a wide range of plugins and customizations to accommodate this. Those extras usually cost extra too.&lt;/p&gt;
&lt;p&gt;While SaaS sites do provide a great starting point with a plethora of potential plugins, in many cases plugins are supplied by 3rd parties. That means that if you have problems with the plugin, you will need to deal with that provider separate from the main service provider.&lt;/p&gt;
&lt;p&gt;A lot of time and money can be spent trying to make diverse systems work together. SaaS can be more “turn-key” in the beginning, but especially for more complex websites, it can end up costing more than if you created a custom site in the beginning.&lt;/p&gt;
&lt;h3 id=&#34;what-vendors-does-your-company-work-with&#34;&gt;What vendors does your company work with?&lt;/h3&gt;
&lt;p&gt;Vendors are sometimes overlooked when trying to decide on what type of website will be needed. Here are some questions which might complicate your website:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do you use a 3rd party to ship or fulfill your products?&lt;/li&gt;
&lt;li&gt;Do you sell your products on Amazon, Google Shopping, or other providers?&lt;/li&gt;
&lt;li&gt;Do you use a vendor to provide your products to you?&lt;/li&gt;
&lt;li&gt;Do you assemble the product after receiving parts from different vendors?&lt;/li&gt;
&lt;li&gt;Does your company use any software for customer management, accounting, or shipping?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your answer is yes to any of these questions, you need to know what platform each of those vendors or platforms use, and if it is compatible with the website you are planning to build. Almost all business done today involves the exchange of information between you, your customer, and your vendors.&lt;/p&gt;
&lt;p&gt;That exchange of information usually takes place through an Application Programming Interface (API). If you aren’t familiar with APIs, here’s a &lt;a href=&#34;https://www.freecodecamp.org/news/what-is-an-api-in-english-please-b880a3214a82/&#34;&gt;great explanation&lt;/a&gt;. Understanding how websites communicate with your vendors is very important.&lt;/p&gt;
&lt;p&gt;The point is that if you plan on doing any volume of business, at some point you will need to exchange information with some vendor or other. Verifying that your new website is capable of exchanging information with existing vendors is a big consideration for you to make &lt;em&gt;before&lt;/em&gt; you build. Building a website without the required APIs would be like building a house without any provision for water, plumbing, or electricity. This is important stuff, and it can get very expensive to retrofit!&lt;/p&gt;
&lt;h3 id=&#34;is-that-all&#34;&gt;Is that all?&lt;/h3&gt;
&lt;p&gt;Absolutely not. There are endless considerations that can play into your decision. But hopefully this post has given you some good ideas of where to start and will help you avoid &lt;a href=&#34;https://en.wikipedia.org/wiki/Analysis_paralysis&#34;&gt;analysis paralysis&lt;/a&gt;. Use this information to get a good idea of your needs and document them, so that you can investigate the right things. Compare how well different solutions fit your needs.&lt;/p&gt;
&lt;p&gt;Who knows, you may start with a SaaS solution for a few years, and then when things are rolling and you have a better handle on your site layout, migrate to a custom-built site. There are no set rules.&lt;/p&gt;
&lt;p&gt;Don’t read an ad for a website service offering to find out you what you need in a website. Determine what you need in your website and look for a product which meets your needs!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Why upgrading software libraries is imperative</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2020/06/why-upgrading-software-libraries-is-imperative/"/>
      <id>https://www.endpointdev.com/blog/2020/06/why-upgrading-software-libraries-is-imperative/</id>
      <published>2020-06-10T00:00:00+00:00</published>
      <author>
        <name>Selvakumar Arumugam</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2020/06/why-upgrading-software-libraries-is-imperative/image-0.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://unsplash.com/photos/PlBsJ5MybGc&#34;&gt;Image&lt;/a&gt; by &lt;a href=&#34;https://unsplash.com/@toluobde&#34;&gt;Tolu Olubode&lt;/a&gt; on &lt;a href=&#34;https://unsplash.com&#34;&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Applications primarily run on front- and back-end programming languages, including library dependencies. Operating systems and programming languages can be periodically updated to run on the latest version, but what about the many libraries being used in the app’s front and backend? As we all know, it can be quite a daunting task to maintain and individually update a long list of software dependencies like the examples later in this post. Still, it is important to keep them updated.&lt;/p&gt;
&lt;p&gt;This post dives into our experience upgrading a complex app with a full software stack and lots of dependencies. We’ll examine the benefits of upgrading, what you will need, and how to go about such an upgrade as simply as possible.&lt;/p&gt;
&lt;p&gt;The app in question contained decade-old software and included extensive libraries when we received it from our client. The app used languages including Java, Scala, Kotlin, and JavaScript along with many libraries. The initial plan was to upgrade the complete software stack and libraries all at once due to the gap between versions. This proved to be more difficult than expected due to a host of deprecated and removed functionality as well as interdependence of a few of the libraries.&lt;/p&gt;
&lt;h3 id=&#34;conflict-approach-dont-update-unless-you-have-to&#34;&gt;Conflict approach: “Don’t update unless you have to”&lt;/h3&gt;
&lt;p&gt;While this can be sustainable in the short term, it quickly becomes less applicable in the long run. One important purpose of updates is to (hopefully) protect from new vulnerabilities and cyber attacks. Scenarios arise where particular library fixes are implemented on the latest version, yet require upgrading other libraries to the latest version in a chain. Because upgraded libraries need extensive testing and preparation for new issues, this directly impacts whether the app attempts to resolve an issue.&lt;/p&gt;
&lt;p&gt;Therefore, smaller and more frequent updates are more sustainable in the long run. Larger and less frequent upgrades will not only result in unexpected errors, but also require more complete regression testing to deliver a bug-free update. The following reasons justify the necessity of software and library upgrades:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They apply timely security patches to reduce vulnerabilities and defend from cyberattack&lt;/li&gt;
&lt;li&gt;You can identify deprecated functionality earlier and use alternatives&lt;/li&gt;
&lt;li&gt;They can apply fixes for known bugs in the library&lt;/li&gt;
&lt;li&gt;They’re based on the latest versions of software or library, encouraging stability&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, staying on the latest major version yields the benefit of applying minor and patch releases seamlessly without risk. Most software and libraries use semantic versioning, formatted as MAJOR.MINOR.PATCH:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MAJOR version - Incompatible API changes&lt;/li&gt;
&lt;li&gt;MINOR version - Add functionality with backward compatiblity&lt;/li&gt;
&lt;li&gt;PATCH version - Bug fixes with backward compatibility&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So being on the latest major versions of libraries allows applying minor and patch releases without breaking existing functionalities of the app.&lt;/p&gt;
&lt;h3 id=&#34;benefits&#34;&gt;Benefits&lt;/h3&gt;
&lt;p&gt;The benefits of keeping software and libraries updated include bug fixes, new features, boosted performance, as well as better stability, compatibility, and security measures. We can often ignore upgrades in projects because we don’t perceive significant effects in appearance or usage. But on closer inspection, frequent updates deliver important advantages.&lt;/p&gt;
&lt;h3 id=&#34;real-time-difficulties&#34;&gt;Real-time difficulties&lt;/h3&gt;
&lt;p&gt;In real-life scenarios, bug fixes and performance optimization of an app often take a higher priority than upgrading libraries. In many cases, this results in a discrepancy between the app’s version and the current version. This discrepancy can lead to the following issues when upgrading libraries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unexpected error handling in new releases&lt;/li&gt;
&lt;li&gt;Unexpected unsupported library dependencies&lt;/li&gt;
&lt;li&gt;Need for complete end-to-end testing due to major version of library upgrade&lt;/li&gt;
&lt;li&gt;Lack of work being visibly completed can lead to a lack of confidence from client&lt;/li&gt;
&lt;li&gt;Difficulty in estimating workload due to major unexpected errors&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following passages offer guidance in how to adequately prepare for these issues.&lt;/p&gt;
&lt;h3 id=&#34;get-prepared&#34;&gt;Get prepared&lt;/h3&gt;
&lt;p&gt;Much can be learned from preparing for a major upgrade on both a business and technical level. First, a complete list of libraries from the entire app should be compiled. This list should include the latest and current version of the library in the app. Reviewing the changelog of both versions will help identify potential incompatibilities or problems. Visiting the “issue report page” of the library to monitor any version-specific issues is also recommended.&lt;/p&gt;
&lt;p&gt;Once you’ve adequately prepared the libraries for upgrading, you can use any method of your choosing to upgrade and maintain the list. Once the roadmap is established, upgrading can commence and compatibility issues that arise can be dealt with as they arise. Finally, thorough end-to-end testing is necessary once the upgrade process is complete.&lt;/p&gt;
&lt;p&gt;Below are some examples of software lists you might have for a project (we left out the latest versions for brevity in this post, but it’s helpful to have a column for those too!).&lt;/p&gt;
&lt;h5 id=&#34;programming-software--servers&#34;&gt;Programming software &amp;amp; servers&lt;/h5&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Software&lt;/th&gt;&lt;th&gt;Running&lt;/th&gt;&lt;th&gt;Release date&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ubuntu Linux&lt;/td&gt;&lt;td&gt;12.04.5&lt;/td&gt;&lt;td&gt;2017-04-28&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;nginx web server&lt;/td&gt;&lt;td&gt;1.12.2&lt;/td&gt;&lt;td&gt;2017-10-17&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Jetty Java Servlet container&lt;/td&gt;&lt;td&gt;9.2.3&lt;/td&gt;&lt;td&gt;2014-09-05&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;JVM/Java&lt;/td&gt;&lt;td&gt;1.7u79&lt;/td&gt;&lt;td&gt;2015-04-14&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Scala&lt;/td&gt;&lt;td&gt;2.11&lt;/td&gt;&lt;td&gt;2014-04-21&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Kotlin&lt;/td&gt;&lt;td&gt;0.9.223&lt;/td&gt;&lt;td&gt;2014-10-23&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Lucene&lt;/td&gt;&lt;td&gt;4.10.0&lt;/td&gt;&lt;td&gt;2014-09-03&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;PostgreSQL database&lt;/td&gt;&lt;td&gt;9.3.10&lt;/td&gt;&lt;td&gt;2015-10-08&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h5 id=&#34;java-libraries&#34;&gt;Java libraries&lt;/h5&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Software&lt;/th&gt;&lt;th&gt;Running&lt;/th&gt;&lt;th&gt;Release date&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;joda-convert&lt;/td&gt;&lt;td&gt;1.3.1&lt;/td&gt;&lt;td&gt;2013-03-01&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;joda-time&lt;/td&gt;&lt;td&gt;2.2&lt;/td&gt;&lt;td&gt;2013-03-01&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;play-json&lt;/td&gt;&lt;td&gt;2.7.0&lt;/td&gt;&lt;td&gt;2019-01&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;httpclient&lt;/td&gt;&lt;td&gt;4.1.2&lt;/td&gt;&lt;td&gt;2011-07-10&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;httpcore&lt;/td&gt;&lt;td&gt;4.1.2&lt;/td&gt;&lt;td&gt;2011-07-22&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;httpmime&lt;/td&gt;&lt;td&gt;4.1.2&lt;/td&gt;&lt;td&gt;2011-07-29&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;commons-codec&lt;/td&gt;&lt;td&gt;1.3&lt;/td&gt;&lt;td&gt;2005-10-01&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;jooq&lt;/td&gt;&lt;td&gt;3.1.0&lt;/td&gt;&lt;td&gt;2013-06-30&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;jooq-codegen&lt;/td&gt;&lt;td&gt;3.1.0&lt;/td&gt;&lt;td&gt;2013-06-30&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;jooq-meta&lt;/td&gt;&lt;td&gt;3.1.0&lt;/td&gt;&lt;td&gt;2013-06-30&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;jtds&lt;/td&gt;&lt;td&gt;1.3.0&lt;/td&gt;&lt;td&gt;2012-10-27&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;servlet-api&lt;/td&gt;&lt;td&gt;3.1&lt;/td&gt;&lt;td&gt;2013-04-25&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;play-json-joda&lt;/td&gt;&lt;td&gt;2.11-2.6.9&lt;/td&gt;&lt;td&gt;2018-03-01&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;lucene-core&lt;/td&gt;&lt;td&gt;4.10.0&lt;/td&gt;&lt;td&gt;2014-09-02&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;lucene-memory&lt;/td&gt;&lt;td&gt;4.10.0&lt;/td&gt;&lt;td&gt;2014-09-02&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;lucene-queries&lt;/td&gt;&lt;td&gt;4.10.0&lt;/td&gt;&lt;td&gt;2014-09-02&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;lucene-queryparser&lt;/td&gt;&lt;td&gt;4.10.0&lt;/td&gt;&lt;td&gt;2014-09-02&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;lucene-highilghter&lt;/td&gt;&lt;td&gt;4.10.0&lt;/td&gt;&lt;td&gt;2014-09-02&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;lucene-analyzers-common&lt;/td&gt;&lt;td&gt;4.10.0&lt;/td&gt;&lt;td&gt;2014-09-02&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;postgresql&lt;/td&gt;&lt;td&gt;9.2-1003-jdbc4&lt;/td&gt;&lt;td&gt;2013-05-27&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;jsoup&lt;/td&gt;&lt;td&gt;1.7.3&lt;/td&gt;&lt;td&gt;2013-11-11&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;jetty-util&lt;/td&gt;&lt;td&gt;9.2.5.v20141112&lt;/td&gt;&lt;td&gt;2014-11-12&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;tika-core&lt;/td&gt;&lt;td&gt;1.16&lt;/td&gt;&lt;td&gt;2017-07-07&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;commons-fileupload&lt;/td&gt;&lt;td&gt;1.3&lt;/td&gt;&lt;td&gt;2013-03-24&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;commons-beanutils&lt;/td&gt;&lt;td&gt;1.6&lt;/td&gt;&lt;td&gt;2005-11-08&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;commons-collections&lt;/td&gt;&lt;td&gt;2.1&lt;/td&gt;&lt;td&gt;2005-11-08&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;commons-digester&lt;/td&gt;&lt;td&gt;2.1&lt;/td&gt;&lt;td&gt;2010-09-24&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;commons-io&lt;/td&gt;&lt;td&gt;1.1&lt;/td&gt;&lt;td&gt;2005-11-24&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;commons-lang&lt;/td&gt;&lt;td&gt;1.0.1&lt;/td&gt;&lt;td&gt;2005-11-24&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;commons-logging&lt;/td&gt;&lt;td&gt;1.0.3&lt;/td&gt;&lt;td&gt;2005-11-17&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;commons-validator&lt;/td&gt;&lt;td&gt;1.0.2&lt;/td&gt;&lt;td&gt;2005-11-24&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;slf4j-api&lt;/td&gt;&lt;td&gt;1.6.4&lt;/td&gt;&lt;td&gt;2011-10-31&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;slf4j-nop&lt;/td&gt;&lt;td&gt;1.6.4&lt;/td&gt;&lt;td&gt;2011-10-31&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h5 id=&#34;javascript-libraries&#34;&gt;JavaScript libraries&lt;/h5&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Software&lt;/th&gt;&lt;th&gt;Running&lt;/th&gt;&lt;th&gt;Release date&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;angular&lt;/td&gt;&lt;td&gt;1.2.11&lt;/td&gt;&lt;td&gt;2014-02-03&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;jQuery&lt;/td&gt;&lt;td&gt;1.10.2&lt;/td&gt;&lt;td&gt;2013-07-03&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;calendar&lt;/td&gt;&lt;td&gt;1.51&lt;/td&gt;&lt;td&gt;2005-03-07&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;calendar-setup&lt;/td&gt;&lt;td&gt;1.25&lt;/td&gt;&lt;td&gt;2005-03-07&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;fckeditor&lt;/td&gt;&lt;td&gt;2.6.11&lt;/td&gt;&lt;td&gt;2014-06-02&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;dom-drag&lt;/td&gt;&lt;td&gt;—&lt;/td&gt;&lt;td&gt;2001-10-28&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;jt_DialogBox&lt;/td&gt;&lt;td&gt;29&lt;/td&gt;&lt;td&gt;2012-08&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;jt_AppDialogs&lt;/td&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;2005-05&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ng-grid&lt;/td&gt;&lt;td&gt;2.0.7&lt;/td&gt;&lt;td&gt;2013-06-07&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ng-grid-flexible-height&lt;/td&gt;&lt;td&gt;2.0.7&lt;/td&gt;&lt;td&gt;2013-06-07&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ng-grid.css&lt;/td&gt;&lt;td&gt;2.0.7&lt;/td&gt;&lt;td&gt;2013-06-07&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&#34;recommendations&#34;&gt;Recommendations&lt;/h3&gt;
&lt;p&gt;Once the app’s software stack and libraries are up to date it’s important to regularly update. The complete upgrade experience can be a rigorous and involved process that includes juggling numerous issues and intensive testing.&lt;/p&gt;
&lt;p&gt;From a client’s perspective, a major upgrade project often doesn’t obviously demonstrate improvement to appearance or function. Because it is not recommended to keep outdated software and major upgrades (such as the one described above) are tedious, the following update options are preferable in order to keep software libraries as up-to-date as possible:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Interval Based:&lt;/em&gt; Particular interval periods are implemented to check versions of software. This minimizes frequency of problems while ensuring a manageable gap between the current and latest software version.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Module Based:&lt;/em&gt; Whenever work is performed on any module for new features or bug fixes, software and library versions are reviewed. This allows for relevant libraries to be updated, tested, and deployed along with development changes within the module.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Even if new features and improvements are not pertinent to the new release, frequent upgrades to software and libraries are crucial in order to ensure the most secure and debugged versions. Please feel free to share your methods of managing software updates in a comment!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>In-House to Consulting, Rinse and Repeat</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2018/03/in-house-to-consulting/"/>
      <id>https://www.endpointdev.com/blog/2018/03/in-house-to-consulting/</id>
      <published>2018-03-28T00:00:00+00:00</published>
      <author>
        <name>Steph Skardal</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2018/03/in-house-to-consulting/burst-image.jpg&#34; alt=&#34;In House vs. Consulting&#34; /&gt;&lt;br /&gt;
&lt;small&gt;&lt;a href=&#34;https://burst.shopify.com/photos/business-team-meeting-in-boardroom&#34;&gt;Photo by Matthew Henry of Burst&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Hi! I’m Steph. I’ve been working 10+ years now as a software engineer, and I’ve spent ~4 years of that as an in-house developer at 2 different companies and 7+ years as a consultant here at End Point and as an independent contractor. Whenever I’ve started a new position, I get asked “What’s it like on the other side?” or something along the lines of “Is the grass greener?” I thought my answer to this was good blog fodder, so here we are.&lt;/p&gt;
&lt;p&gt;If you google “in-house vs. consultant”, much of the results are written from the perspective of a company looking to hire either in-house engineers or looking to outsource to consulting companies. Here’s my approach to answer the question as it relates to employee happiness, skill development, and job satisfaction.&lt;/p&gt;
&lt;h3 id=&#34;working-as-an-in-house-engineer&#34;&gt;Working as an in-house engineer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Working as an in-house engineer can mean that you may focus on one technology (or one web stack) and even one main codebase, although this isn’t necessarily true. When I worked for &lt;a href=&#34;https://www.backcountry.com/&#34;&gt;Backcountry.com&lt;/a&gt; a while back, the main application was an ecommerce application running on &lt;a href=&#34;https://www.interchangecommerce.org/&#34;&gt;Interchange&lt;/a&gt;, and that’s where I spent most of my dev time. But as my experience grew, I began working on other internal B2B tools as well.&lt;/li&gt;
&lt;li&gt;With a small team, it’s possible you might adopt consistent style rules in the code.&lt;/li&gt;
&lt;li&gt;In an engineering role as an in-house dev, you might not be directly involved in sales efforts of the company.&lt;/li&gt;
&lt;li&gt;With a small, single team, there is only one set of team dynamics that you have to navigate between, which might allow you to build stronger relationships with those team members and understand how to work with those team members efficiently. Of course the disadvantage of this is if you don’t get along with a team member, you should learn how to work with them.&lt;/li&gt;
&lt;li&gt;Working as an engineer for a product company might mean a steady stream of income and less micromanaging of expenses. This &lt;em&gt;might&lt;/em&gt; translate to benefits like maternity leave, simply because the revenue stream can support paid leave, but this isn’t necessarily true and highly dependent on the circumstances. On the flip side, if the company isn’t doing well financially, there isn’t a resource for additional income, which could translate to loss of jobs for employees.&lt;/li&gt;
&lt;li&gt;From my experience, working with a small team, there have been better processes in place for code review and code feedback, ultimately resulting in better growth of individual engineers. I have found that while I was an in-house engineer, I did a deep dive into one technology stack, and my skills greatly improved with that depth of experience.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;working-as-a-consultant&#34;&gt;Working as a consultant&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Working as a consultant often offers the ability to be exposed to many technologies, many technology stacks, and more variety.&lt;/li&gt;
&lt;li&gt;From my experience, adaptability is highly valued in the consulting space because you are exposed to different technology stacks and development processes. It is valuable to move seamlessly between teams and technologies.&lt;/li&gt;
&lt;li&gt;Depending on how your company is set up, there can be a wide range of types of client interaction. Some clients want to learn how to make website changes and your role is to support them in that desire. Other clients may be hands-off all dev work, expecting you to have the expertise to drive technology choices. Clients may have very limited budgets and want a consultant to provide the most value to them. Client management is very important here.&lt;/li&gt;
&lt;li&gt;In consulting, from my experience, it is not unusual to participate in sales efforts to provide estimates or technical solutions for proposals.&lt;/li&gt;
&lt;li&gt;While I find many successful software engineering consultants have a breadth of knowledge, companies can often grow talent in specific areas or with specific hires to gain a depth of knowledge in specific technologies. The benefit to other employees is the access to expertise that may translate to better efficiency for clients (for example when I ping other expert co-workers when a question is not in my skillset).&lt;/li&gt;
&lt;li&gt;By nature, consulting is diverse, so job stability may be decent if clients are overall successful and you are successful in working with them.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;working-for-a-company-that-does-both-consulting-and-product-development&#34;&gt;Working for a company that does both consulting and product development&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;I’ve seen a few companies that have been successful in both consulting and product development, where their employees develop a product but supplement company income with expert consulting.&lt;/li&gt;
&lt;li&gt;From an employee perspective, this may offer a nice balance between breadth and depth in working on specific technology stacks.&lt;/li&gt;
&lt;li&gt;A company that does both product development and consulting successfully may be more stable financially due to diversified income streams.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;in-house--consulting&#34;&gt;In-house &amp;amp; consulting&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;In both scenarios, I’ve found there is always a feedback loop going on in during active software development. You complete some task, pass it on for review, wait for feedback from a &lt;em&gt;decision maker&lt;/em&gt; to iterate to the next step or adjustments. I like to fill in time when I’m waiting by working on another feature (in-house) or other client work (consulting).&lt;/li&gt;
&lt;li&gt;My personal experience has taught me that communication is one of the most valuable assets to have as a software engineer, because you are responsible for translating business needs to software. The better you can communicate with intent, the more efficient you will be as an in-house engineer and as a consultant.&lt;/li&gt;
&lt;li&gt;The ability to calculate work effort and manage priorities is also a highly valued skill in both employment circumstances.&lt;/li&gt;
&lt;li&gt;From my own experience, I’ve been lucky to receive flexibility in both scenarios working half/​part-time since my first daughter was born. In the consulting space, working limited time may be suitable for limited client budgets, but as an in-house engineer working half-time translated to less output while still providing knowledge from previous experience.&lt;/li&gt;
&lt;li&gt;I’ve also found that in both scenarios, some job satisfaction comes from the happiness of the client (or &lt;em&gt;decision maker&lt;/em&gt;), which can put you in a difficult position if your client isn’t happy. Every time the &lt;em&gt;decision maker&lt;/em&gt; walks away dissatisfied, I think you have an opportunity to improve how to communicate and work with them to build a successful relationship.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;conclusion-is-the-grass-greener-on-the-other-side&#34;&gt;Conclusion: Is the grass greener on the other side?&lt;/h3&gt;
&lt;p&gt;If you ask me “What’s the best option for me?”, I can’t answer that for you in your particular circumstances. I think an in-house position establishes a good foundation in a single set of technologies that could be beneficial as you progress in your career should you choose to climb the ladder in your current position or move to a consulting position. But if you are adaptable, and want to grow your breadth of experience and exposure to technologies, I think consulting is a good fit.&lt;/p&gt;
&lt;p&gt;In true consulting form, I can only suggest to anyone considering a job change from one to another that you evaluate factors such as job satisfaction, compensation, flexibility, and stability when you are evaluating your options.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Reconciling Android source code</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2017/12/android-reconciling-source/"/>
      <id>https://www.endpointdev.com/blog/2017/12/android-reconciling-source/</id>
      <published>2017-12-19T00:00:00+00:00</published>
      <author>
        <name>Zed Jensen</name>
      </author>
      <content type="html">
        &lt;p&gt;Recently, a client came to us with an interesting problem. They needed some changes made to an internal-use Android app that had been created for them by another company, but they didn’t have up-to-date source code for the app, and they had no way of getting it. They gave us an old archive of source code, a more recent working build of the app, and asked us to figure it out.&lt;/p&gt;
&lt;p&gt;The working version of the app they sent us was built in early 2016, and the app was compiled for Android SDK version 22, which is 5.1 Lollipop. It came out in March 2015, so it was a year old even when the app was created, and the code was using lots of features which have since been deprecated.&lt;/p&gt;
&lt;p&gt;After putting this source code in a Git repository, I started by building the app from the source they’d sent and comparing it to the working version. It looked mostly the same, but a couple of features were broken. At the suggestion of a coworker, I used &lt;a href=&#34;https://github.com/Konloch/bytecode-viewer/releases&#34;&gt;BytecodeViewer&lt;/a&gt; to decompile the APK and took a look around.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2017/12/android-reconciling-source/bytecode-viewer.jpg&#34; alt=&#34;BytecodeViewer screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;It was a little while before I was able to find any differences between the source we had and this decompiled code, but I did find a few logic differences. The source was also using a few old APIs that needed to be updated. With the needed changes made to the source code, I soon had a working build of the app that matched the functionality of the built APK we had.&lt;/p&gt;
&lt;p&gt;This wasn’t the only thing wrong with the app, however. Another hurdle in picking up this project from its previous developers showed up when I had to fix a few odd problems reported by the users. One problem was on an information screen listing attributes of items. An example:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2017/12/android-reconciling-source/details.jpg&#34; alt=&#34;Details screen&#34;&gt;&lt;/p&gt;
&lt;p&gt;The “Quantity” field worked just fine for any non-zero value, but if it was 0, the app was displaying 16 instead. This turned out to be very simple to fix. Below is the layout code involved:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;TextView&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;android:layout_width=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;wrap_content&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;android:layout_height=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;wrap_content&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;android:textAppearance=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;?android:attr/textAppearanceMedium&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;android:text=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;16&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;android:textColor=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;@color/background_black&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;android:id=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;@+id/txt_info_quantity&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The default text of that field was, likely as a placeholder, set to 16, and it wasn’t being overwritten when the given value was 0. So, all I had to do was replace it with 0, since it would be overwritten anytime there was a nonzero value.&lt;/p&gt;
&lt;p&gt;This was a good reminder to somehow keep track of placeholders like this, for example, putting a todo comment or something similar, so bugs like this can be caught in code reviews.&lt;/p&gt;
&lt;p&gt;Figuring out how to reconcile the source and binary of this app seemed like a daunting task, but it turned out to be very doable, and was a very interesting project.&lt;/p&gt;

      </content>
    </entry>
  
</feed>
