Java-Projekte automatisch erzeugen

Es gibt praktische Software und dann gibt es manchmal Anwendungen bei denen man sich fragt was genau der Anwendungszweck ist. Eine dieser Anwendungen ist der Java Bullshifier. Die einzige Aufgabe des Java Bullshifier ist es, riesige Java-Projekte zu erzeugen.

Die Projekt-Webseite

Selbst im Vorstellungsartikel des Tools wird die Meinung vertreten, das es ein wenig esoterisch wirkt. Im Artikel wird allerdings ebenfalls die Motivation bzw. die Nutzung des Tools beschrieben:

It’s used in order to test some of our monitoring capabilities over ridiculously large code bases, with transactions that go thousands of calls deep, over thousands of classes, and end up with exceptions.

Erzeugt werden ein Projekt mit einer beliebigen Anzahl an Klassen und für eine Klasse sieht der generierte Quelltext exemplarisch wie folgt aus:

package generated.afz.qen.lrlj;

import helpers.Config;
import helpers.Context;
import java.util.*;
import java.util.logging.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;

public class ClsTvxlbccvg
{
    public static final int classId = 325;
    static final Logger logger = LoggerFactory.getLogger(ClsTvxlbccvg.class);

    public static void metWrkbglgpwrbj(Context context) throws Exception
    {
        int methodId = 0;
        Object[] root = new Object[8];
        Map<Object, Object> valUmbeeuzlkcg = new HashMap();
        Object[] mapValTaglolagfcm = new Object[10];
        String valLjtuhkvukba = "StrHwrvspzqwyp";

        mapValTaglolagfcm[0] = valLjtuhkvukba;
    
        for (int i = 1; i < 10; i++)
        {
            mapValTaglolagfcm[i] = Config.get().getRandom().nextInt(1000);
        }

        Set<Object> mapKeyGfqzkkkweud = new HashSet<Object>();
        long valZqatretqosu = 2690648861024756176L;

Der Quelltext des Java Bullshifier ist auf GitHub zu finden. Er ist unter der MIT-Lizenz lizenziert und damit freie Software.

Kittens Game

Das Land der Browsergames verfügt über eine Menge Einwohner. Darunter gibt es einige Perlen zu entdecken wie z.B. Candy Box. Eine weitere Perle im Land der Browsergames ist Kittens Game. Bei dem Spiel geht es darum Stück für Stück eine Katzenzivilisation aufzubauen. Was am Anfang simpel wirkt, weitet sich im Laufe des Spieles zu einer komplexen Simulation aus, welche das Spiel immer interessanter macht.

Kittens Game

Auf grafischen Schnickschnack wird dabei verzichtet, so das die “Textwüste” die Fantasie anregt, wie bei alten Textadventures. Das Spiel beginnt in der Steinzeit, führt den Spieler Stück für Stück in das Mittelalter, bis man schließlich nach etlichen Spielstunden in der Neuzeit ankommt. Dort betreibt man dann ein Weltraumprogramm und verlässt den Katzenplaneten und erforscht die Weite des Alls. Der Quelltext ist auf BitBucket zu finden, allerdings ist er nicht unter einer freien Lizenz verfügbar. Stattdessen nutzt es die selbst verfasste WET PAWS LICENSE:

Kitten game is licensed under a WET PAWS LICENSE.

You are free to make any changes in the code for personal or educational purpose. 
Using the game code for commercial gain or creation of derivative works is not permitted.

Hosting a translated version of the game is permitted as long as the game retains all links.
And for god's sake please don't make huge idiotic red logos of your website. (Yes, u77 folks, I am talking about you).

Technisch basiert das Spiel auf HTML5 und dem Dojo Toolkit. Neben der Variante im Browser existieren mittlerweile Versionen für iOS und Android.

Kittens Game
Preis: 2,29 €
Kittens Game
Preis: 1,99 €

Die App-Versionen sind kompatibel zu dem Spielstand des Browsergames, so das man nahtlos auf den mobilen Geräten weiterspielen kann. Die Spielstände können hierfür exportiert werden. In den neueren Versionen von Kittens Game ist der Im- und Export mittels Dropbox möglich, so dass die Übernahme eines Spielstandes noch einfacher ist.

Quellcode durchsuchen

Manchmal ist man als Entwickler auf der Suche nach einem Stück Quellcode. Die Gründe dafür sind vielfältig und natürlich kann man für diesen Zweck die Suchfunktionen einzelner Portale wie GitHub und Co. nutzen um den gewünschten Quelltext zu finden.

searchcode in Aktion

Einfacher wird das ganze mittels searchcode.com, einer Quelltextsuchmaschine. Bei searchcode, werden nach eigenen Angaben, über sieben Millionen Projekte verschiedenster Plattformen durchsucht. Für den Gebrauch in Firmen, welche natürlich auch private Repositories betreiben, gibt es searchcode dabei auch als Lösung zum selberhosten. Der Quelltext von searchcode ist auf GitHub zu finden. Zu beachten ist hierbei, das es sich um keine freie Software handelt und man damit die Lizenzbedingungen bei der Eigennutzung des Servers genau lesen sollte.

Quelltext einer Mediawiki-Seite anzeigen

Vor einiger Zeit hatte ich einen Twitter-Bot entwickelt welcher als Datenquelle unter anderem die Wikipedia nutzt. Dazu nutzt der Bot unter anderem eine Bibliothek um auf die MediaWiki-API zuzugreifen. Nun stellte ich fest das die Nutzung der API in diesem Fall allerdings überdimensioniert war. Stattdessen ist es möglich sich für eine beliebige MediaWiki-Seite denn Quelltext anzeigen zu lassen. Die URL sieht dabei wie folgt aus:

https://de.wikipedia.org/wiki/Machinima?action=raw

Durch den Parameter action=raw wird der Quelltext anstatt des HTML-Renderings ausgegeben und kann somit ausgewertet werden.

Quelltext im Visual Studio automatisch formatieren

Das Visual Studio formatiert den Quellcode automatisch nach den eingestellten Richtlinien. Wenn man nun aber die Richtlinien ändert, steht man vor dem Problem, das der Quelltext noch nach den alten Richtlinien formatiert ist.

Die Formatierungseinstellungen im Visual Studio

Die Formatierungseinstellungen im Visual Studio

Leider gibt es keine direkte Option im Visual Studio um den bestehenden Quelltext am Stück neu zu formatieren. Allerdings kommt man mit einem kleinen Makro (abgeleitet vom VS Formater Macro) an dieser Stelle weiter. Dazu wird im Visual Studio die Package Manager Console (zu finden unter Tools -> NuGet Package Manager -> Package Manager Console) geöffnet und dort folgendes eingegeben:

function f($projectItems) { $projectItems | ? { $_.Name -ne $null -and $_.Name.EndsWith( ".cs" ) -and -not $_.Name.EndsWith( ".Designer.cs" ) } | % { $win = $_.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}') ; $win.Activate() ; $DTE.ExecuteCommand('Edit.FormatDocument') } ; if ($projectItems) { $projectItems | % { f($_.projectItems) } } }
 
$dte.Solution.Projects | % { f($_.ProjectItems) }

Das Visual Studio öffnet nun alle *.cs Dateien in der geöffneten Solution und formatiert die Quelltexte neu. Dieser Vorgang ist dabei relativ langsam und führt bei größeren Projekten dazu das das Visual Studio einfriert. Auf Stack Overflow gibt es eine elegantere Lösung:

function FormatItems($projectItems) {
    $projectItems |
    % {
        # Write-Host "    Examining item: $($_.Name)";

        if ($_.Name -and $_.Name.ToLower().EndsWith(".cs") `
            -and (-not $_.Name.ToLower().Contains(".designer."))) {

            $win = $_.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}');
            $win.Activate();

            $dte.ExecuteCommand('Edit.FormatDocument');

            if (!$_.Saved) {
                Write-Host "    Saving modified file: $($_.Name)";
                $dte.ExecuteCommand('File.SaveSelectedItems');
            }

            $dte.ExecuteCommand('Window.CloseDocumentWindow');
        }

        if ($_.ProjectItems -and ($_.ProjectItems.Count -gt 0)) {
            # Write-Host "    Opening sub-items of $($_.Name)";

            FormatItems($_.ProjectItems);
        }
    };
}

$dte.Solution.Projects | % {
    Write-Host "-- Project: $($_.Name)";

    FormatItems($_.ProjectItems)
}
;

Bei dieser Lösung wird jede Datei nach der Neuformatierung, gespeichert und wieder geschlossen. Leider wird auch diese Lösung von Datei zu Datei langsamer, so das sie für größere Projekte wiederrum unbrauchbar ist. Mit der Extension Format Document gibt es eine Lösung welche schnell genug ist, allerdings funktioniert diese nur unter Visual Studio 2010. Nach einigen Anpassungen habe ich eine Version gebaut, welche auch unter Visual Studio 2012 und 2013 läuft. Das Problem an dieser Variante ist, das Dateien in Ordnern nur berücksichtigt werden wenn der Ordner im Solution Explorer geöffnet ist. Alles in allem ist keine der vorgestellten Lösungen wirklich optimal, allerdings kann man viele Fälle mit den vorgestellten Lösungen lösen.