Handling JavaScript Dependencies with Gradle

In the Java world and with build tools like Maven or Gradle, you are used to declarative dependency management. Simply declare which libraries and versions you need, and let the build tool download and package these libs for you. The artifacts are typically stored in an artifact repository like Archiva, Artifactory or Nexus.
What is quite common for JAR dependencies seems to be quite uncommon for JavaScript dependencies. In my experience, a lot of Java projects that have a JavaScript front end still store the JavaScript libraries in a VCS.

I recently noticed (thanks to Steffen Schäfer) that Gradle, my current build tool of choice, is capable of handling JavaScript dependencies, too.
This is how it works:

Upload your required JavaScript library with a POM to your artifact repository.

  • inside the POM, use packaging js
  • to make it a valid POM, add the javascript-maven-plugin as an extension

Here is a full sample of such a POM:

<?xml version="1.0" encoding="UTF-8"?>
<project
  xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>de.oio</groupId>
  <artifactId>mylib</artifactId>
  <version>1.0.0</version>
  <packaging>js</packaging>

  <name>Some name</name>
  <description>A really nice description</description>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <build>
    <extensions>
      <extension>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>javascript-maven-plugin</artifactId>
        <version>2.0.0-alpha-1</version>
      </extension>
    </extensions>
  </build>

</project>

In your Gradle build script (build.gradle), add a new configuration js and declare your dependencies for this configuration.

configurations {
    js
}

dependencies {
    js 'de.oio:mylib:1.0.0'
}

Using configurations.js, you can access the JavaScript files as a fileset. A typical scenario is to include these JavaScript files into a WAR archive.
You can do this as follows.

apply plugin: 'war'

war {
    into('js'){
        from configurations.js
    }
}

Transitive dependencies are also supported. If mylib has a dependency to anotherlib, simply declare it in the POM of mylib:

<dependencies>
  <dependency>
    <groupId>de.oio</groupId>
    <artifactId>anotherlib</artifactId>
    <version>1.0.0</version>
  </dependency>
</dependencies>

You could also define a POM that has no corresponding artifact itself, but it includes a lot of dependencies. A use case for this could be a POM that simply includes all the JavaScript libraries that you use in all of your projects. To do so, simply create a POM with packaging pom and a dependencies block.

Posted in Build, config and deploy, Web as a Platform | Tagged , , , , , | Leave a comment

TCP and HTTP for web developers

When developing web applications, you can do some mistakes related to basic peculiarities of TCP and HTTP. The post explains some of the pain points and shows approaches to avoid such problems.

Continue reading

Posted in Web as a Platform | Tagged , , , , , | Leave a comment

JavaScript Caching – Adopting Perfect Caching for JS Apps

The Problem

JavaScript Single-Page-Applications tend to consist of a lot of JavaScript files. Several hundreds of JS files are no exception.

When accessing these applications using a web browser, every single JavaScript file has to be fetched using a distinct request. Unfortunately, browsers support only a limited number of parallel connections/requests. Older versions of Internet Explorer were limited to only two concurrent connections. Most modern browsers support six to eight concurrent connections, but this is still not enough to effectively fetch several hundreds of files.

Additionally, JS frontends these days can be several megabytes in size which need to be fetched from the server.
This results in wait times and high server load.

To reduce the wait time and server load, one could cache these files in the browser.

But how long should these files be cached?
And when they are cached and you deploy a new release of your application, users would have to delete their browser cache manually, which is not very practical.
Continue reading

Posted in Web as a Platform | Tagged , , , , | 1 Comment

Git Workflows Tutorial 3: Workflows in der Praxis

In den bisherigen Beiträgen wurden die Grundlagen zu Git Workflows definiert und anschließend einige Workflows betrachtet. Freilich nicht unerwähnt bleiben sollte die Tatsache, dass all die vorgestellten Mechanismen wie Code Review, Pull Request oder Merges von Werkzeugen unterstützt durchführbar sind. Dies soll Gegenstand dieses Beitrags sein.

Continue reading

Posted in Agile Methods and development, Atlassian Tools, Build, config and deploy | Tagged , , , | 1 Comment

Git Workflows Teil 2: Workflows meistern

Nachdem wir im vorigen einige Grundlagen zu Workflows und ein erstes Beispiel betrachtet haben, geht es nun ans Eingemachte. Wir vergleichen Workflows und machen uns Gedanken über den praktischen Einsatz von Workflows im alltäglichen Geschäftsbetrieb.

Continue reading

Posted in Agile Methods and development, Build, config and deploy | Tagged , , | Leave a comment

Git Workflows Teil 1: Warum wir Workflows brauchen

In dieser Artikelserie werden wir das in der Software-Entwicklung inzwischen omnipräsente Phänomen Git Workflows näher betrachten. Im ersten Teil betrachten wir das Wie und Warum hinter Git Workflows, bevor wir uns im zweiten Teil konkreten Workflow-Modellen widmen. Im dritten Teil beantworten wir die Frage, wie man eigene Workflows mithilfe von Werkzeugen geschickt umsetzt.

Ein typisches Szenario in einer Softwareschmiede könnte so aussehen: Eine gemeinsame Codebasis, mehrere Mitarbeiter oder sogar Teams und ein stabiler master-Zweig, von dem aus veröffentlicht werden soll. Ein “zweig-affines” Versionskontrollsystem soll her, denn Zweige gehören zum guten Ton – also setzt man auf Git. Warum eigentlich? Benutzt jeder heutzutage. Wie das im Detail funktioniert, ist ja auch nicht so wichtig.

Continue reading

Posted in Agile Methods and development, Build, config and deploy, Politics | Tagged , , | Leave a comment

String Deduplication zum Sparen von Speicherplatz in Java 8

Strings nehmen in den meisten Anwendungen den Großteil des Speicherplatzes ein. Wobei wir es hierbei nicht selten mit Duplikaten zu tun haben.
Häufiger Verursacher ist hierbei das Laden von Objekten aus externen Quellen wie Datenbanken oder das Parsen von externen String basierten Requests. Werden Entitäten in großen Mengen (z.B. Adressen) geladen,

public class Address {
   private String strasse;
   private String plz;
   private String ort;
   ...
}

so wird für jede Entitäten-Instanz Speicherplatz für die entsprechenden String-Instanz-Variablen reserviert. Am Beispiel von Adressen können wir uns gut vorstellen, dass hierbei die gleichen Ortsbezeichnungen wie “Hamburg” häufig in mehreren Adressinstanzen vorkommen und jeweils Speicherplatz zur Ablage des char-Arrays benötigt. Bei großen Datenverarbeitungen wird entsprechend viel Speicherplatz verwendet. Auch viele Leer-String Objekte können beobachtet werden.
Continue reading

Posted in Java Basics, Java Runtimes - VM, Appserver & Cloud | Tagged , , , | Leave a comment