A Web developer’s reading list

Manning is planning to release a free book sampler that would include chapters from different books covering modern Web development process. They asked me to select books/chapters and write a short intro, which I did and decided to share this with you.

The modern world of Web development requires software engineers who are well versed in multiple disciplines. Of course, familiarity with the JavaScript syntax is a must. As Atwood’s law states, “Any application that can be written in JavaScript, will eventually be written in JavaScript”. Well, maybe not in the pure JavaScript, but in its more productive superset called TypeScript.

Web developers use frameworks and/or libraries to avoid re-inventing the wheel while working on applications. While many people are still happy with jQuery, more progressive developers are debating: Angular or React? This comparison is wrong because React is a library while Angular is a framework with batteries included. But Angular and React are the most popular tools in the Web development ecosystem today.

There is a trend to develop applications using principles of reactive programming. The data consumer subscribes to the data stream that’s pushed to the consumer only when the data is available. This is an alternative to the polling model that requires the client to make periodic requests for data, which may or may not not be available. The RxJS library implements the push model via observable streams of data. This library offers you a variety of chainable operators (functions) that handle and transform the data en route.

Making your application available on mobile devices is important. Will your Web application look good on a small screen or you’d better create separate native applications for each mobile platform? There is is a third approach to create so called hybrid applications that run a Web container inside your mobile device translating HTML elements into their native counterparts. Actually there is a forth approach that suggests reusing the most of the code base of your Web app while compiling the UI portion into native mobile components before the app is deployed. NativeScript is one of the frameworks that does it.

Most Web applications would need to provide login and user authentication/authorization. The chances are that you’ve been offered by some apps to login using their FaceBook or Twitter account. Usually such authorization is implemented using OAuth protocol. You can set up authorization using privately installed OAuth server that fits nicely with RESTful Web services.

This book sampler will give you a taste of multiple facets of the modern development of Web and mobile applications. Some of the books are already released while others are still in the works, but you can reading drafts via Manning’s MEAP program.

For this sampler I’ve suggested selected chapters from the following books:

1. RxJS in Action MEAP

2. Angular 2 Development with TypeScript

3. React in Action MEAP

4. NativeScript in Action MEAP

5. OAuth 2 in Action MEAP

This is not a complete list and there are other fine books being released by many book publishers. Here’s my message to you

“Read.Study.Write.Repeat.”

Happy reading!

Advertisements

Dear community or my response to Dear JavaScript

I decided to write this blog after reading the post “Dear JavaScript” by James Kyle. In short, James write about how the anger and negativity in some posts/comments hurt people who work tirelessly developing open source software. I’d like to take this discussion a step higher and talk about online communities in general and growing the thick skin.

I do understand James’ feelings first hand. Been there. Produced a lot of free content online. Wrote more than a 1000 blogs in English. Recorded 500 audio podcasts in Russian . Published multiple free video trainings watched by hundreds of thousands people. In short, I’ve produced a lot of content. Some of it was of great quality IMHO, and some of it could be better.

At least I tried.

But no matter what content you produce, as long as it’s consumed by a dozen people expect getting some criticism, which, for the most part will be constructive, because these people belong to your close circle. But as the number of consumers grows, you’ll start getting angry or even hateful feedbacks. With thousands of consumers, expect direct insults.

Haters gonna hate.

It took me a while to stop paying attention to negative feedback as long as I believed that I did a good job. You can’t be loved by everyone. Let’s take my Intro to Java video. It was watched by more than a 100,000 people, got 1,000 likes and 18 dislikes. This tells me that I did a great job. Should I worry about 18 dislikes. Not a bit. Not everyone has to like my content, style, voice, or the shape of my nose. Vast majority of comments are positive and thankful except this one(I translate it from Russian): “This is almost the most stupid and disgusting presenter I’ve ever seen.” This comment put a smile on my face. I took me a while to grow thick skin, but if the majority of people approve your work, I’ll continue doing what I enjoy.

I’m following a very interesting person on Instagram. Her name is Nika. She travels the world, posts beautiful photos, and writes excellent notes (in Russian) to her posts. You can’t even imagine how many hateful comments she gets. Originally this photo  was taken by her teenage son Gregory, who created his own site. Here’s an abridged translation of their dialog:

– Mom, could you add a link to my Web site. I can go public already, can’t I?
– Sure you can, but first let me show you something. Here’s the collection of comments written about your mom (90% were written by women). These are their faces, and they will inevitably come to your site to watch you.
After reading silently for about five minutes Gregory’s face became pale, and he asked:
– Mom, why are they doing this? What’s wrong with them? Why do they hate you so much?
– Greg, this is not hatred. They tell us about themselves and their fears. I personally have nothing to do with this. They don’t care who to write about. I’m their mirror and it’s very painful for them to look into this mirror. Fear=pain=hatred. Are you ready? Are you sure you won’t get upset?
– Mom, don’t publish the link to my site.

Then Nika concludes. This may be not very pedagogical, but he’s a big boy now. Let him know the difference between “for what” and “why”.

In the past, most Internet users were consumers of some published content. Now anyone can easily produce and self-publish any content. Moreover, with the advances of blogging platforms, CSS, and typography no matter what you publish will look as a professionally produced article (regardless of its content). Yes, I’m talking about medium.com. Who cares that every blog on medium looks the same? They look better than the online edition of the New York Times.

Unfortunately, many social networks are poisoned by angry, destructive comments that may hurt good people like James Kyle. The only social network that stands out as a friendly place for everyone is StackOverflow. After earning the 2000 reputation you are allowed to edit posts of other users. Maybe that’s one of the reasons people love going to StackOverflow. No negativity there

So dear Internet community, be f@@king polite to other people. Respect the work done for you by others. Especially, if they did it for free. If you don’t like some content, suggest improvements. Don’t expose your black souls. Peace.

Categories Web

Be careful with authorization servers

These days people are accustomed to logging in to various Web sites using third-party authorization services. Do you want to login using your Facebook or Twitter account? In technical terms, this means that you are being offered to delegate the process of authorization to a third-party service offered by Facebook, Twitter or other big guys.

You’re sick and tired of creating and remembering dozens of IDs/passwords for all theses online services. Please, please login me quickly using whatever service you want. Most of such services are implemented with OAuth protocol, which allows to use the user’s account on some other servers to authorize you for accessing someone’s Web site. The good part is that OAuth servers do not reveal your id/password, but perform the authorization returning a special encoded token that will be used as you temporary passcard. The access to your Facebook or Twitter account will be limited.

1

The concept of giving a limited access to a resource is easily explained to rich people, who have these fancy cars with the ignition key that includes a removable small key so you can lock the glove compartment (full of diamonds) while giving a large key to a valet parking attendant. If you’re not that rich yet, take a look at this image:

2

Say you are visiting a Web site xyz.com, with offers you login with one of your social networks’ account. Creators of xyz.com must reveal what exactly they will be able to do with your credentials. It’s great that they won’t be able to login to your Twitter account, but will they be able to tweet on your behalf or start following people? Always read text on such login windows before clicking on that easy-to-login button.

I’ll give you a couple of examples. Here’s how Right Relevance offers you to login to their site:

3

With all my respect to Right Relevance for their good technical content, I wouldn’t want them to post tweets for me. Thanks, but no thanks.

Here’s another one. In April I was speaking on OAuth authorization at a Java conference in Moscow, Russia. In the evening I went to see a show in a popular theatre, which offered a free Wi-Fi hotspot. Nice! When I tried to connect to this spot from my phone I got this message:

4

Thank you, Hot Wi-Fi, but you’re not that hot for letting you tweet for me. Besides, it’s not polite to browse the Internet while watching a play with famous actors.

One more example, and I’ll let you go. This morning I’ve received an email that someone I know sent me a private message via a social network called Zorpia. I don’t know where are these people learning about such services, really. Anyway, you don’t have to be a rocket scientist to guess what Zorpia wants for showing me that private massage:

5

No, for some reason I don’t want you to manage my contacts. I frequently get emails that start like this: “John Smith is updating his contact information at the social network xxx.com and asks you to login and update your cell phone number there”. Needless to say that xxx.com starts with offering me to login with one of the popular OAuth servers, and I’d say “No”.

Don’t blame the OAuth protocol, which has all provisions for restricting the access for these third-party applications. There is a special scope parameter that allows to specify what a third-party app can do on your behalf. For example, here’s the description of the scope parameters for the developers who want to delegate authorization to Google’s OAuth servers.

Here’s my message to you: “Think twice before letting some Web application to delegate the authorization process to someone else.” Read the fine print!

Partying with IntelliJ IDEA Dart, Java, WebSocket and Glassfish

Recently I wrote a blog showing how to use the WebSocket protocol to push the data from a Java server to a JavaScript client. This time I’ll keep the same code on the server, but the client will be written in Dart. For this example I was using GlassFish 4.1 server, and IntelliJ IDEA 14.1 with installed Dart plugin. I also have Dart 1.9.1 SDK. My goal was to create one Web application deployable module that would contain both Java and Dart code.

I’ll be brief assuming the the reader has some familiarity with IntelliJ IDEA IDE and the structure of Dart projects. Repeating the same exercise in Eclipse IDE should be a trivial task too.

By the time I was creating this app, I already had an IntelliJ IDEA project with multiple Dart modules. So I wanted to add a new Java module with Dart support to the same project. If you prefer creating a new IDEA project from scratch, instead of creating a new module create a new project. Here’s how I did it:

1. Create a new GlassFish configuration (IDEA menu Run | Edit Configurations) pointing at the existing GlassFish installation.

2. Create a new module of type Java Enterprise selecting GlassFish as an application server Web Application and WebSocket as additional libraries. IDEA will create a project with directories src and web (the latter will contain the WEB-INF dir). I called my module GlassfishWebsocketDart. IDEA will also generate index.jsp, which you can delete.

GlassFish_Idea

3. Go to the Project Structure (Cmd ; ) and add GlassFish, GlassFIsh WebSocket, and Dart SDK as dependencies to the module GlassfishWebsocketDart.

4. Create (or copy from an existing Dart module) the files pubspec.yaml and pubspeck.lock into the root dir of your module.

5. Create index.html and main.dart in the web dir. The file index.html can look like this:

 
<!DOCTYPE html>
<html><head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="scaffolded-by" content="https://github.com/google/stagehand">
    <title>hello</title>

</head>

<body>

  <div id="output">dart uber</div>

  <script type="application/dart" src="main.dart"></script>
  <script data-pub-inline src="packages/browser/dart.js"></script>
</body></html>

My file main.dart looks as follows:

import 'dart:html';

main() {

  var output = querySelector('#output');

  WebSocket ws = new WebSocket('ws://localhost:8080/GlassfishWebsocketDart_war_exploded/clock');

  ws.onOpen.listen((event){
    output.text = &amp;amp;quot;Connected&amp;amp;quot;;
  });

  ws.onMessage.listen((event){
    output.text = event.data;
  });
}

6. Open main.dart in the editor and IDEA will show the option Enable Dart support – click on it.

7. Right-click on the pubspec.yaml and run pub build (select the debug mode). It’ll create the folder build with files and dart packages required for deployment.

build

8. Copy all the files from the build/web dir into the web dir located in the root of your module.

9. In the src directory create the following file WebSocketClock.java

import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@ServerEndpoint("/clock")
public class WebSocketClock {

    static ScheduledExecutorService timer =
            Executors.newSingleThreadScheduledExecutor();

    private static Set<Session> allSessions;

    DateTimeFormatter timeFormatter =
            DateTimeFormatter.ofPattern("HH:mm:ss");
    @OnOpen
    public void showTime(Session session){
        allSessions = session.getOpenSessions();

        // start the scheduler on the very first connection
        // to call sendTimeToAll every second
        if (allSessions.size()==1){
            timer.scheduleAtFixedRate(
                    () -> sendTimeToAll(session),0,1,TimeUnit.SECONDS);
        }
    }

    private void sendTimeToAll(Session session){
        allSessions = session.getOpenSessions();
        for (Session sess: allSessions){
            try{
                sess.getBasicRemote().sendText("Local time: " +
                        LocalTime.now().format(timeFormatter));
            } catch (IOException ioe) {
                System.out.println(ioe.getMessage());
            }
        }
    }
}

10. IDEA can deploy Java web apps in the exploded mode (default) or as an WAR archive. Open the GlassFish configuration (menu Run | Edit), and it should look like this:

gf_exploded

11. Run your GlassFish and you should see the server pushing the local time every second. The Chromium browser runs the client’s code in its Dart VM, which properly runs WebSocket client communicating with the Java server.

chromium

You may ask, “Will this app work in other browsers that don’t have (and will never have) Dart VM?”. Good question. Theoretically the last two lines in our index.html file should check the presence of Dart VM and replace the references to main.dart with a reference to the JavaScript main.dart.js that was generated by the pub build process.

  <script type="application/dart" src="main.dart"></script>
  <script data-pub-inline src="packages/browser/dart.js"></script>

In practice this may not happen, and you’d get a 404 on “missing” dart.js. Now you have two choices:

a) Manually replace the above two lines with this one:

 <script src="main.dart.js"></script>

b) Add a dependency to your project to use the transformer dart_to_js_script_rewriter to do this replacement automatically. Your modified pubspec.yaml should look like this:

name: 'glassfish_websocket_dart'
version: 0.0.1
description: >
  A web app that illustrates dart, websocket, and glassfish.
environment:
  sdk: '>=1.0.0 <2.0.0'
dependencies:
  browser: any
  dart_to_js_script_rewriter: any
transformers:
  - dart_to_js_script_rewriter

Now run the pub get and pub build and only the JavaScript version will be used. This should be done only if you decide to deploy my useful application in production.

The other improvement that can be done are to create a deployment artifact that builds a WAR file that will include the content from the Dart build folder as well as compiled Java classes. And those who already cut the IDE umbilical cord should automate build and deployment with gradle and gulp.

In April, I’ll be making the presentation “Dart for Java developers” twice. On April 14 I’ll do it online at the New York Dart Users Group, and on April 23 I’ll do a live presentation for the New York Java SIG.

Update for MAC OS users: After upgrading to 10.10.3 GlassFish doesn’t start unless you change the startup line to
/Users/yfain11/glassfish4/glassfish/bin/asadmin start-domain –verbose

Introducing AngularJS to Java Developers

If you want to develop Web applications, you’ll need to learn JavaScript. But writing code in JavaScript (at least in its ECMAScript 5 incarnation) is non-productive. You need to pick up a one of the JavaScript frameworks, because:

  • they make you more productive
  • will deal with cross-browser compatibility and make the application more structured
  • may include reusable components
  • lower the amount of manually written code.

JavaScript market offers multiple frameworks and libraries. While frameworks expect you to programs using well defined ruleswithin a certain code structure, libraries just offer reusable components a la cart.

In turn, frameworks can be categorized as feature complete (rigid app structure, intrusive, rich GUI components, tooling) and lightweight (MVC + Binding + Routing)
.

Ext JS, YUI, and Dojo represent feature-complete frameworks. AngularJS, Backbone.js, and Ember are examples of lightweight frameworks. After years of experimenting with different frameworks and libraries we decided to stick with hugely popular AngularJS by Google.

I work in a Java shop, and one of my responsibilities is to create an conduct trainings (both internal and external). Several years ago I started to work with our engineers on the curriculum introducing AngularJS to an enterprise Java developer.

The learning curve of AngularJS is not too steep for Java developers, who understand the concept of containers, dependency injections, callbacks. They must become proficient with JavaScript with its functions, closures and other good stuff.

But equally important is to be familiar with todays tooling of a productive Web developer. Here’s a short list of tools that JavaScript developers use today:

  • npm – node package manager used for installing and managing development tools
  • yeoman – a scaffolding tool used to generate the initial structure of an application
  • bower – package manager for application dependencies
  • grunt – a build automation tool
  • A JavaScript testing framework

The next decision to make is how to communicate with the Java backend. Forget about JSP, servlets, and JSFs. Preparing HTML in your Java code is out of fashion. A Java server exchanges the JSON-formatted data with a single-page HTML/JavaScript front end, which use either AJAX techniques (old) or WebSocket protocol (new).

On the Java side we like to use such tried and true technologies as RESTful Web service and Java Messaging API.

When we hire a AngularJS/Java developer, we expect him to be familiar with at least 90% of all the above buzzwords. Finding such skilled software engineers may be difficult, so we’ve created a training program to prepare such a person.

By now, we’ve taught and fine-tuned this training class multiple times. The latest online version of this class consists of seven weekly training sessions (3.5 hours each) and seven consultations (from 30 to 60 min each). Programmers learn and gradually apply all of the above tools and techniques while working on the Online Auction application that has the following architecture:

javaauction-1

We have a great feedback from people who have completed this training. But everyone says it’s challenging. And it should be. Back in the nineties a person who knew one of the programming languages plus SQL could relatively easy get a well paid job. Not anymore.

Why You Should Start Developing With Google Dart

In the summer of 2013 I wrote a blog “How Serious is Google About Dart“. It’s January of 2015, and I’d like to give you an update from the trenches. Our team has developed and deployed in prod a beta version of the application that helps consumers with finding and rating insurance agents and getting quotes online. The front end of EasyInsure is written in Dart language.

Before introducing the Dart ecosystem, I’d like to give you a little background about our prior experience in developing Web applications (I work for Farata Systems).

On the server side we always use Java and have no plans to switch to any other technology. After spending many years developing the front end with Adobe Flex framework and ActionScript programming language we got spoiled by this super-productive environment. After the mankind led by Apple killed Flash Player, we started to look for an alternative.

Back in 2005 we’ve abandoned JavaScript, but decided to give it another chance. Things were a little better this time. JavaScript has better IDEs and browser-based tools for developers. The number of JavaScript frameworks and libraries went down from two hundred to a couple of dozens, which is a good thing.

Still, the productivity of our developers dropped substantially in JavaScript comparing to what we’ve seen with Flex. I can’t give you exact numbers, but it looks like developing in Flex is at least three times faster than with any JavaScript framework we tried (ExtJS,AngularJS, and lots of small libraries). When I say JavaScript, I mean its version based on the ECMAScript 5 specification.

In 2013 we got familiar with the Google Dart language. The syntax of the language was pretty appealing and easy to understand. It felt like Java, but a little more modern. Dart is optionally-typed language. You can run the compiled Dart code in DartVM, but no browser except Dartium support it, and it’ll remain this way. Generating JavaScript from the Dart code is a realistic way of delivering Dart applications for any browser today.

But any language without the proper tooling is doomed, and this is what makes Dart stand out. Here’s the list of tools available for Dart Developers:

1. The IDEs: Dart Editor from Google and WebStorm from JetBrains. We use Dart Editor because it’s smarter than WebStorm today.
2. dart2js is a Dart-to-JavaScript compiler and a tree-shaker, which removes the unused code from the third-party libraries used in the application.
3. pub is a dependency management, development server and build tool.
4. gulp is a task manager. It’s an analog of Grunt or Gradle. We use gulp to prepare optimized ready-to-deploy application from the code produced by the pub build. In particular, we do the gzip compression there.
5. Dartium is a Web Browser for developers. Google Chrome is based on the open source project called Chromium, and Dartium is Chromium with built-in DartVM. We use it for launching and debugging applications.
6. Dump-Info Visualizer – allows to inspect the generated JavaScript. It gives a very convenient breakdown by the application’s JavaScript code so we can analyze file sizes and identify the scripts to be optimized.
7. Observatory is Dart profiler (we haven’t used it yet).
8. AngularDart framework. It’s a port of a popular JavaScript framework AngularJS.

The above list is pretty impressive, isn’t it? As Google Dart evangelists say, “Batteries included”.

Developing JavaScript applications in Dart is definitely more productive. I do recommend you to start learning Dart and develop the front end of your Web applications in this developer-friendly environment. Having said that, I’d like to warn you that there are no jobs on dice.com that require programmers with Dart skills. Oops… Moreover, three years from now your Dart skills may be in even lesser demand in the enterprise world. Oops…

After these two oopses half of the readers may lose interest to Dart, because it doesn’t meet their career objectives. For those of you who continue reading I’ll explain why IMHO you still should learn and use Dart today. Because the final release of ECMAScript 6 (ES6) is around the corner. Because this spec already gave birth to JavaScript 6 (it’s a boy)!

By the way, do you know why there is no enterprise jobs that require Dart skills? Because enterprise architects will fight hard against any language that runs in a browser unless it’s called JavaScript. Back in 2007 Adobe sales force did a great job by pushing Flex framework into enterprises. Enterprise architects were fighting hard against Flex then, and they will do the same with Dart. But Google is not Adobe. They won’t fight for Dart in enterprises.

But promoting Dart in your organization can be easy. Just explain your enterprise architects that programming in Dart is just a smart way of preparing the enterprise to embrace the bright JavaScript 6 future with classes,modules, promise, fast image rendering, et al. The code that you’ll be writing in Dart during the next 12-18 months will need to be converted into EcmaScript 6 as soon as several major Web browsers will start supporting it.

The syntax of Dart and ES6 are literally the same. Google invested time and resources in creation of IDE for Dart, and now they’re working on the IDE for ES6. Even manual refactoring of the code from Dart to ES6 shouldn’t be a major project, but I’m sure this process will be automated soon.

As a matter of fact, some browsers already started supporting ES6. See for yourself:

dartblog

I’d like to draw your attention to the greenest column on the right side. Yes, it’s the successor of the today’s funniest browser known as IE! Microsoft calls it Spartan, and promises that Spartan will be a lightweight browser that feels like Chrome or Firefox. You just can’t go wrong with such a name.

Spartan already supports ES6. Courageous early adopters can start developing code in ES6 now, than compile the code down to ES5 with Traceur compiler and deploy it in any today’s browser. But if you want to work in a tools-rich environment just develop your single-page applications in Dart and AngularDart. Give the ES6 some time to mature. The work on ES7 is being done too, and it looks very interesting and promising.

I’ve created a New York City Dart Meetup with a hope to get some Manhattan-based firm to host our meetings in the future. Meanwhile we’ll run our meetings online so you’re welcome to join no matter where you are located. Go Dart if you need to deliver today!

Why Java Applets should be banned

During my training classes on Web development with Java I used to ask students this question, “Do you think it would be a smart move if Amazon.com would create their online store using Java Applets?” The right answer is “Yes, if their goal is to go out of business.”

While back in 1995 Java was introduced to the world with the help of Applets (remember that dancing Duke?) this technology was buried by Microsoft (remember that law suit between Sun and Microsoft back in 1998)?

Web applications written with Java Applets would require the user to have the Web browser supporting specific JRE required by the applet. If in the past I was joking that a truck driver from Alabama would not be able to install the proper JRE on his computer, now I have to admit that I ran into a serious issues with this as well. Here’s my story.

I need to run a Webinar for O’Reilly on Tuesday. This will be a second one. The first one was three months ago. When I was testing the software for presenters, I was told not to use Chrome browser, cause they use Web conference software from on24.com, which doesn’t support Chrome. Why? Because they use Java for the Web client. Fine. I started the Firefox, installed the Java plugin and was able to run the Webinar. Disclaimer: three months ago I was using Java 7 under MAC OS X.

Today I use Java 8. I decided to practice with On24 software for the upcoming seminar and got Java errors. Sent a stack trace to O’Reilly, they contacted On24, and I got an answer: uninstall Java 8 from your computer and install Java 7. On24 Webinar platform doesn’t support Java 8, which was released six months ago. WAT?

But I don’t want to uninstall/reinstall Java just to run a Web conference. It’s 2014 for crying out loud! As a matter of fact I have both Java 7 and 8 installed on my MAC OS 1.9.4. Can I just configure my MAC OS to use Java 7? In the past, MAC System Preferences would allow to select the Java version – not anymore. Found a script to run during the boot of my Macbook to make it use Java 1.7. Great, it worked, but only for applications – typing java -version in the Terminal window properly reported Java 7. Unfortunately Firefox uses its own Java plugin that still sees my Java 8, and the On24 applet still crashes. Firefox on MAC doesn’t offer installing older versions of the Java plugins for security reasons. Actually, replacing Java 8 JavaAppletPlugin.plugin from the Internet Plugins folder with the one from Java 7 will make Firefox happy, but the applet from On24 still doesn’t work properly.

I’m not a truck driver from Alabama, but I’m about to give up and will uninstall Java 8 just to run this Webinar. Hope this will help.

Amazon is not stupid. They would never develop a Web front end with Java applets. But On24.com should seriously consider modernizing their Web conferencing platform unless their goal is to go out of business.