Skip navigation
1 2 3 Previous Next

Ondrej Zizka's Blog

101 posts

See this: ECMAScript 6: New Features: Overview and Comparison

Thanks to Marek for finding this.

Past few months, I've been working with Angular 2. I didn't pick it, rather been forced to. In a good sense. We use it as UI tech for Red Hat Migration Toolkit, AKA project Windup - for it's web UI. I was pushing my (still) favorite Apache Wicket, which, by the way, is picking up Java 8 goodies to make UI coding even greater pleasure. I even created a PoC UI for managing the apps, with JPA 2 and all. But someone else, much more senior than me, was pushing Angular 2, which at that time was .alpha1 or so. It was very clear to me that learning this ball of craziness glued together by a dozen of libraries, frameworks, hacks and tools, will take loooong time. And it does. But I told to myself - f it, let's see how crazy things can get. And let's add that to my skill set. If I will learn this, then I will learn anything.  And I gave up pushing Wicket, with which I believe we would be a bit further in web UI features (but that's highly speculative).


Now what. I am still learning it all, as it has many, many dark corners. I came from Java world, and I was shocked by the chaos in JavaScript world. Nothing is for sure, there's lack of documentation, integration often breaks, micro versions break compatibility, there's little you can rely on - typically, only the top few libraries are well tested, documented, and maintain backward compatibility. On the bright side, the development pace is impressive. But to what end? To me, it seems that the whole ecosystem recipitantly, wildly, yet slowly, is getting closer to what mature development platforms have for years or decades. That's true for all aspects: Dependencies management, centralized repository, syntax, OOP, reflection, debugging, logging, UI templates, expression language, exception handling, ... but this doesn't happen following a plan. There are no specifications, no drafts. The common ground is basically only EcmaScript, or better said, what the browsers that majority of people have, implement.


Fun fact: My bachelor's thesis back in 2004 was about contemporary JavaScript, showing how cool language that actually is, how it can emulate classes, and how it can be used for complex applications. To prove that, I programmed a cover of Harrel W. Stilles' Miner VGA game for DOS, a basic Turing machine emulator, and an implementation of a neural network with backpropagation, simulated annealing and that AI stuff. In short, JavaScript was my beloved toy language. I'm not saying it's not now, just what has grown around it now, most of all, reminds me this:



Anyway - this series (if it becomes a series, that is) won't be about complaints, rather the landmines I've stepped on with a spectacular few-hours flight through the air of console.log()-based debugging and deciphering the Angular stacktraces (which are useless most of the time as they only contain references to Zone.js).


I don't want to complain all the time to my team how Angular2 or other JS thing hurt me today, so I'll drop my daily frustration here. Maybe someone will find it interesting, funny or even usable - in which case, good for you

I've digged another tiny tool I wrote in the past. This time it's CSV Cruncher.


This tool takes a few .csv files and turns them into SQL tables.

Then you can query the data and export another CSV.

This gives you all the power of SQL, if you consider you can use all the tricks like self-joins, recursive selects, triggers, stored procedures. It uses HyperSQL.


Want to give it a try? Check out here: GitHub - OndraZizka/csv-cruncher


Since Google dumped Google Code and trashed all the code on it, I've lost it (it's on some old disk but who knows where).

So the version on Github is decompiled (by Windup).

If it wouldn't work, file an issue and let me know, I will fix

Ondrej Zizka

IDE file open script

Posted by Ondrej Zizka Dec 20, 2016

This might come in handy.

You write ` FooBar` and it most likely opens what you are looking for:


1) Tries to open the path.

2) If it doesn't exist, it tries to open that file anywhere in the directory tree (provided it has some of the file name suffixes I currently use).

3) If not exists, it opens the files that contains a type of that name (class, function, interface).

4) If not found, it opens the files that contain given pattern.


This blog's source WYSIWYG is buggy so it's hard to edit, the up-to-date version is at gist.


set -x


## If the argument is a path to a file, open it.
if [ -f "$1" ] ; then
  "$NB" "$1"

## Else if it's a path in a form of foo*bar (contains a star), open all that match, of types .java, .ts, .html, .xml, .ftl
elif expr "$1" : ".*\*.*" ; then 
  find . -path "./*/target/*" -prune -o \( -name "*$1*".java -o -name "*$1*".ts -o -name "*$1*".html -o -name "*$1*".xml -o -name "*$1*".ftl \) -print | xargs $NB

## Else if there's a TypeScript class of that name, open it.
git grep -q -E "(class|function) +$1"
elif [ $? ] ; then 
  git grep -l -E "(class|function) +$1" | head -n $MAX_FILES_TO_OPEN | xargs "$NB"

## Else open whatever matches the given pattern.
  COUNT=`git grep -l "$1" | wc -l`
  if [[ "$COUNT" -gt "$MAX_FILES_TO_OPEN" ]] ; then echo "Too many `git grep` matches, taking first $MAX_FILES_TO_OPEN."; fi
  git grep -l "$1" | head -n $MAX_FILES_TO_OPEN | xargs "$NB"

JDK 9 is about to be released somewhere in Q3 2017. There's a huge list of non-trivial new features, see below.

So in the meantime, you can have a look at this good guide what's coming upon us: The Ultimate Guide to Java 9


Compiler level properties still not there, what a disappointment. They might be in JDK 11, hopefully. This whole story reminds me how Czech highways are being built.


JEPs targeted to JDK 9, so far

102: Process API Updates
110: HTTP 2 Client
143: Improve Contended Locking
158: Unified JVM Logging
165: Compiler Control
193: Variable Handles
197: Segmented Code Cache
199: Smart Java Compilation, Phase Two
200: The Modular JDK
201: Modular Source Code
211: Elide Deprecation Warnings on Import Statements
212: Resolve Lint and Doclint Warnings
213: Milling Project Coin
214: Remove GC Combinations Deprecated in JDK 8
215: Tiered Attribution for javac
216: Process Import Statements Correctly
217: Annotations Pipeline 2.0
219: Datagram Transport Layer Security (DTLS)
220: Modular Run-Time Images
221: Simplified Doclet API
222: jshell: The Java Shell (Read-Eval-Print Loop)
223: New Version-String Scheme
224: HTML5 Javadoc
225: Javadoc Search
226: UTF-8 Property Files
227: Unicode 7.0
228: Add More Diagnostic Commands
229: Create PKCS12 Keystores by Default
231: Remove Launch-Time JRE Version Selection
232: Improve Secure Application Performance
233: Generate Run-Time Compiler Tests Automatically
235: Test Class-File Attributes Generated by javac
236: Parser API for Nashorn
237: Linux/AArch64 Port
238: Multi-Release JAR Files
240: Remove the JVM TI hprof Agent
241: Remove the jhat Tool
243: Java-Level JVM Compiler Interface
244: TLS Application-Layer Protocol Negotiation Extension
245: Validate JVM Command-Line Flag Arguments
246: Leverage CPU Instructions for GHASH and RSA
247: Compile for Older Platform Versions
248: Make G1 the Default Garbage Collector
249: OCSP Stapling for TLS
250: Store Interned Strings in CDS Archives
251: Multi-Resolution Images
252: Use CLDR Locale Data by Default
253: Prepare JavaFX UI Controls & CSS APIs for Modularization
254: Compact Strings
255: Merge Selected Xerces 2.11.0 Updates into JAXP
256: BeanInfo Annotations
257: Update JavaFX/Media to Newer Version of GStreamer
258: HarfBuzz Font-Layout Engine
259: Stack-Walking API
260: Encapsulate Most Internal APIs
261: Module System
262: TIFF Image I/O
263: HiDPI Graphics on Windows and Linux
264: Platform Logging API and Service
265: Marlin Graphics Renderer
266: More Concurrency Updates
267: Unicode 8.0
268: XML Catalogs
269: Convenience Factory Methods for Collections
270: Reserved Stack Areas for Critical Sections
271: Unified GC Logging
272: Platform-Specific Desktop Features
273: DRBG-Based SecureRandom Implementations
274: Enhanced Method Handles
275: Modular Java Application Packaging
276: Dynamic Linking of Language-Defined Object Models
277: Enhanced Deprecation
278: Additional Tests for Humongous Objects in G1
279: Improve Test-Failure Troubleshooting
280: Indify String Concatenation
281: HotSpot C++ Unit-Test Framework
282: jlink: The Java Linker
283: Enable GTK 3 on Linux
284: New HotSpot Build System
285: Spin-Wait Hints
287: SHA-3 Hash Algorithms
288: Disable SHA-1 Certificates
289: Deprecate the Applet API
290: Filter Incoming Serialization Data
292: Implement Selected ECMAScript 6 Features in Nashorn
294: Linux/s390x Port
295: Ahead-of-Time Compilation
297: Unified arm32/arm64 Port

Windup 3.0 will be a web application. It can still be used as command line application, but on top of that, you can deploy Windup to a JBoss WildFly (or EAP) and scan your applications from a nice web UI.


Look at Windup Migration Platform and try migrating your application to the newest Java EE.


From the developers perspective, the frontend stack is Angular 2, TypeScript, ReactJS, Keycloak for security, and few other libraries. It's a bit pain for me to learn the new paradigm and to leave the very comfortable Java ecosystem, but on the other hand, looks like all the JavaScript-centered craziness is going to stay around for a couple of decades and eventually settle down, so why not embrace it (thinking, "Banzaaaii!!" )

Look at GitHub - windup/windup-web: Windup as a Web Service  if interested in code.



When coding against Titan graph database, you may encounter the exception below.

In our case, we are using Tinkerpop Frames, and one frame was using the same value for an edge label as other for a property.





To fix that, simply use different values.

Caused by: java.lang.IllegalArgumentException: Querying for edges but including a property key: project
  at com.thinkaurelius.titan.graphdb.query.vertex.BasicVertexCentricQueryBuilder.constructQuery(
  at com.thinkaurelius.titan.graphdb.query.vertex.VertexCentricQueryBuilder.execute(
  at com.thinkaurelius.titan.graphdb.query.vertex.VertexCentricQueryBuilder.titanEdges(
  at com.thinkaurelius.titan.graphdb.query.vertex.VertexCentricQueryBuilder.edges(
  at com.thinkaurelius.titan.graphdb.vertices.AbstractVertex.getEdges(
  at com.tinkerpop.blueprints.util.wrappers.event.EventVertex.getEdges(
  at com.tinkerpop.frames.annotations.AdjacencyAnnotationHandler.removeEdges(
  at com.tinkerpop.frames.annotations.AdjacencyAnnotationHandler.processVertex(
  at com.tinkerpop.frames.annotations.AdjacencyAnnotationHandler.processElement(
  at com.tinkerpop.frames.annotations.AdjacencyAnnotationHandler.processElement(
  at com.tinkerpop.frames.FramedElement.invoke(
  at com.sun.proxy.$Proxy111.setProject(Unknown Source)

Windup has another version out - 2.7.0.Final.

Download at the Windup website.

What's new?

The main addition is the rules for EAP 5 to EAP 7 rules.

Use the --target eap:7 parameter to use them.

Thanks Marek for all the hard work and all who contributed the knowledge.




PS: There's one little, tiny, bug which was not found until a live demo, so if you hit that, please wait for next release or fix with the jar in the attachment.

On Friday, Windup 2.6.0.Final was released. Download at the Windup website.


There are 2 particular things to highlight:



Windup 2.6 can create a basic Maven project structure for your application. When you execute Windup with the --mavenize flag, Windup analyzes the structure of your application and creates POM files with the appropriate dependencies for each of your application modules.


Shared archives

If a big application contains same libraries or modules multiple times appear in multiple places in your input applications, and adjusts incident counts and effort estimates to avoid double-counting. If you analyze multiple applications together, Windup bundles information about the shared archives to present you with information on the common libraries shared across your applications.


Besides that, like always - performance improvement, bug fixes, design improvements, additional rules & rules fixes.



When you validate a XML file, and this has a XSD URL for some namespace, and this XSD URL redirects to another URL, then the default EntityResolver2 takes that as a failure.

Jess noticed (and fixed) this when debugging WINDUP-997.


So for instance, this XML was not valid, because some of the URLs (perhaps in the linked XSD's) is behind a redirect:


<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns=""

    <mvc:resources mapping="/resources/**" location="/" />



So here's a fixed implementation. It follows only a single redirect, but change the if to a for and it will follow more (don't forget to prevent infinite loop).


package org.jboss.windup.rules.apps.xml.xml;


import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.ext.EntityResolver2;

* This is an {@link EntityResolver2} that has been enhanced to support URL redirection.
 * @author <a href="">Jesse Sightler</a>
public class EnhancedEntityResolver2 implements EntityResolver2
  public InputSource getExternalSubset(String name, String baseURI) throws SAXException, IOException
  return null;

  public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
  return resolveEntity(null, publicId, null, systemId);

  public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId) throws SAXException, IOException
  URL url = baseURI != null ? new URL(new URL(baseURI), systemId) : new URL(systemId);

  URLConnection connection = url.openConnection();

  // Not a HTTP connection... skip redirection logic
  if (!(connection instanceof HttpURLConnection))
  return new InputSource(connection.getInputStream());

  HttpURLConnection httpConnection = (HttpURLConnection)connection;

  int status = httpConnection.getResponseCode();
  if ((status != HttpURLConnection.HTTP_OK) &&
  (status == HttpURLConnection.HTTP_MOVED_TEMP
  || status == HttpURLConnection.HTTP_MOVED_PERM
  || status == HttpURLConnection.HTTP_SEE_OTHER))
  String newUrl = httpConnection.getHeaderField("Location");
  httpConnection = (HttpURLConnection) new URL(newUrl).openConnection();

  InputSource inputSource = new InputSource(httpConnection.getInputStream());
  return inputSource;



There was a bug which proved itself in more complicated rules with nested conditions.

If you were the ones who it gave a headache to, here's a gift for you


WINDUP-1057 Composite conditions (not, and, or) need to pass the nam… by OndraZizka · Pull Request #943 · windup/windup…



A great new feature is comming in Windup 2.6.0.


In real life scenarios, if a company has multiple .ear applications, it's very likely that they will bundle various subcomponents, for instence, EJB jars with EJB's used across the company.


In Windup 2.4.0, we added the ability to analyze multiple applications. But that didn't count with the fact stated above. That lead to these re-used submodules being counted multiple times in the migration effort and total incidents sums, which doesn't reflect the real amount of effort - once the submodule is done, it's done for all applications.


So since Windup 2.6.0, this behavior is corrected. If Windup spots some libraries which are used multple times, it will create a "virtual" application in the report, called "<shared-libs>" and  1) report it only once, 2) analyze it only once (the other copies of the same jar won't be re-scanned).


Kudos to Jess for implementing this!



I've recorded a short video about what's Windup.

What's Windup in 6 minutes - Windup 2.5 brief intro - YouTube


If you like it, please share with whoever might be interested.



Actually it's a cover of Brad Davis' original video for Windup 0.x, so kudos to him for a nice script.

Here's what I used to create the JBoss AS 6 matrix:

GitHub - OndraZizka/jboss-as-component-matrix-xslt: Creates a component matrix CSV for JBoss Application Server.

And this is what it creates:

Component Matrix History

Could be reworked for EAP 7+ as well, if there's nothing better yet....

After Google code was discontinued, I am pulling my project out of there as needed. Hopefully I'll get all of them before they shut it down for good.

This one is already deleted, so I had to find it in an old SVN repo at one of of old drives.


MavenHoe turns a directory into a Maven repository.

Here's how it works:


Mavenhoe – fake Maven repository from .jar's in local directory tree


QA dept often needs to  run a maven project with "faked" dependencies - the actual .jar files  must be taken from a product's distribution, which are not in any Maven  repository (like EAP's .zip or RPM distribution).


This  utility is one of the ways to solve this problem. It scans a given  directory for .jar files, indexes them, and opens a server acting as a  Maven repository, in the sense of serving the indexed .jar files.


Which file will be served is determined by match of  strings in the provided Maven URL path  (localhost:17283/<group>/<artifact>/<version>/<filename>.jar).  This algorithm is a matter of future improvement. Using static mapping  file is a possibility.




Maven project  preparation


Optionally disable the central repository if  you shouldn't need it - i.e. all your dependencies should be in the  directories indexed by Mavenhoe.

See . One (IMO the best) option is to override it in pom.xml:




Add  Mavenhoe repository to your pom.xml:



Alternatively,  you can also add the repo to ~/.m2/settings.xml (or  any path and use `mvn -s settings-local.xml`):


<?xml version="1.0" encoding="UTF-8"?>


    <!-- Mavenhoe fake repository -->


Mapping  file

Mapping file tells Mavenhoe which file should be served for  certain G:A:C:V axes.

You can provide multiple mapping files,  using parameter -map <path/map.txt>


An  example of such file is the attached to :


# Format:

# <real-file-name>    <groupId>                  <artifactId> [@<cls>] <version>    <virtual-file-name>

jboss-managed.jar      org/jboss/man/            jboss-managed        2.1.0.SP1    jboss-managed-2.1.0.SP1.jar
getopt.jar            gnu-getopt/                getopt                1.0.12-brew  getopt-1.0.12-brew.jar
jboss-kernel.jar      org/jboss/microcontainer/  jboss-kernel          2.0.6.GA      jboss-kernel-2.0.6.GA.jar
jboss-logging-spi.jar  org/jboss/logging/        jboss-logging-spi    2.1.0.GA      jboss-logging-spi-2.1.0.GA.jar



The  first column is path to a file which should be served (base  dir is the current) to Maven client.

Further columns are: groupId (with either  slashes or dots), artifactId, [@classifier,]  version, artifact file name, respectively.

Classifier can be optionally specified at fourth column, prepended with @  (shifting all remaining columns).


For JBoss  products, these information info will be acquired from an online  database (see ).



Command line options

Command  Format (hopefully the syntax is clear ):


mavenhoe [-sp] ( -map [-fakepoms] <map.txt> | -i [-fakepoms] <dir> | -ipom <dir> )+


Header  1Header  2
-i [-fakepom]  <path/to/dir>

Indexes .jar files in this dir tree.

G:A:V used:

1) META-INF/pom.xml if  present.

2) filename : filename : MANIFEST.MF's  Implementation-Version.

-ipom  <path/to/dir>As with -i,  only searches for pom.xml files.
-map [-fakepom] <path/map.txt>Mapping  file to be used by FileBasedMapper.
-spStrip paths from the 1st column in all map files. (applies  to all -map's).

Applied to next dir tree; Mavenhoe will serve fake .pom files with no dependencies.

G:A:C:V used are as described above.



Meta  URLs



            Will list all indexed jars.



            Will list FileBasedMapper's maps.



            Shuts the server down.

Artifact URLs


HTTP codeMeaning


Requested  artifact was found, and is server in the response body. See the DEBUG  log messages for details.
400Wrong  G:A:V path - not in a format <groupId>/<artifactId>/<version>/<filename>.<packaging> .
403Payment required - send  donation to author's PayPal .-)
404Requested  artifact was not found. See DEBUG logs what was searched.
409FileBasedMapper  found a match in a mapping file, but the referenced artifact file does  not exist (nothing to serve).
500Internal  exception - bug in the app.




-  Should give 404



-  Should let you download the hibernate-core-3.3.2.GA_CP03.jar



Build  process tips


To ensure that your dependencies are not  downloaded from local Maven repository, wipe them out:

mvn build-helper:remove-project-artifact


To  use trully "local" repository solely for one project, set it to be in a  directory.

This can be done by using modified settings.xml.


cp ~/.m2/settings.xml ./settings-local.xml

sed "s|<localRepository>\(.*\)</localRepository>|<localRepository>local_repo</localRepository>|" -i settings-local.xml
mvn -s settings-local.xml ...


Sample  log output


2010-12-10 00:38:25,692 DEBUG  Looking for: jdom : jdom : 1.0 : jdom-1.0.jar
2010-12-10 00:38:25,693 DEBUG  Looking for: jdom : jdom : 1.0 : jdom-1.0.jar
2010-12-10 00:38:25,693 DEBUG    Thus  for: 'jdom:jdom'
2010-12-10 00:38:25,693 DEBUG    Supposed file name: null
2010-12-10 00:38:25,693 DEBUG  Looking for: jdom : jdom : 1.0 : jar = jdom-1.0.jar
2010-12-10 00:38:25,693 DEBUG    Supposed file name: jdom
2010-12-10 00:38:25,693 DEBUG

  Found: JarInfo{ name: jdom, version: 5.1.0 (build: SVNTag=JBPAPP_5_1_0 date=201009150028),

                  group: null,

                  path: eap/jboss-eap-5.1/jboss-as/server/production/deploy/admin-console.war/WEB-INF/lib/jdom.jar,

                  base: eap }