Monday, October 30, 2023

Fixing the default settings for a webMethods Integration Server

 

Having installed a webMethods Integration Server, there are a few defaults, that you would like to change. (If you know them.) The you, in that case, would be a person like me, a webMethods developer. In most cases, that's the first thing I do, after the server's first lauch. Let's discuss them.


Extended Settings


In general, it's worth to know all the extended settings. Unfortunately, there are too many of them to know even the majority. However, I found the following to be particularly relevant for me:

  •  watt.server.compile, and watt.server.compile.unicode: These manage, how to launch the Java compiler, if you are editing Java services. In general, the defaults (Something like javac -classpath {0} -d {1} {2}.) are fine. However, note that the {0} is being replaced by the IS classpath. And, that can become extremely long. Too long for a Windows command line.
    My definite recommendation would be, to clear these settings (empty string as the value). That will cause IS to use the Java Compiler API, instead of the command line. In that case, the length of the classpath doesn't matter.
  • watt.server.httplog: By setting this to "common", you will get an additional log file <INSTANCE_DIR>/logs/http.log, which is basically like the Apache server's access log. This is important information, if you want to know, whether a client actually reaches  IS, or not.
  • watt.server.ns.hideWmRoot: If you ever walked through your integration servers packages directory, you might have noticed an unknown package, named WmRoot. If so, you might also have noticed, that this package is not in the list of packages, that the IS Administration UI, and Designer display to you. Well, here's why: By setting this variable to "false", that package becomes visible
    Knowing that package is certainly not necessary. However, sooner or later in your career as a webMethods developer, you'll find yourself wondering "How does one do X?", where X is something, that you would usually do in the IS Administration UI.
    Well, the answer to your question would most likely be something "The UI does this by invoking the service wm.server.whatever:DoX in the WmRoot package.
    Warning: While it is common practice to use services in WmRoot, at least for tasks like "Is Y a valid package, or service name?", you should be aware, that they are not part of the public IS API. In other words: As soon as you start using such services, you are starting to pile up a migration risk for your next upgrade. You are warned!
  • watt.server.ns.lockingMode: Set that to none. It's your development server, so no harm done. If you need to align with coworkers, use a proper version control system, aka Git.

The mess, that is business.

 Typo of the day: "Busimess requirements". Should teach that to my f...ing auto correction. :-)


Wednesday, April 28, 2021

Installing native Docker on AlmaLinux

 

Today, I had to reinstall a Docker host, which was previously running on my beloved CentOS 8. As that is quickly approaching it's end, I decided to give AlmaLinux a try. To use it as a Docker host, I had to install native Docker. (I prefer to use native Docker over the one, that is part of the distribution.) So, according to https://get.docker.com/, this is supposed to work as follows:


    curl -fsSL https://get.docker.com -o get-docker.sh
    sudo sh get-docker.sh

In the past, I did that on CentOS, quite a lot, so I expected it to work out of the box. Unfortunately, that didn't quite work, and failed with the error message below:


    sudo sh get-docker.sh
# Executing docker install script, commit: 7cae5f8b0decc17d6571f9f52eb840fbc13b2737 ERROR: Unsupported distribution 'almalinux'


In other words, the Docker installer isn't quite uptodate. Fortunately, fixing a shell script isn't that big of a problem, and I got it running by applying the following patch:

[jwi@gitjndhost ~]$ diff -ub get-docker-orig.sh get-docker.sh --- get-docker-orig.sh 2021-04-28 12:10:12.477498011 +0200 +++ get-docker.sh 2021-04-28 12:03:23.300011495 +0200 @@ -342,7 +342,7 @@ esac ;; - centos|rhel) + centos|rhel|almalinux) if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then dist_version="$(. /etc/os-release && echo "$VERSION_ID")" fi @@ -427,8 +427,8 @@ echo_docker_as_nonroot exit 0 ;; - centos|fedora|rhel) - yum_repo="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE" + centos|fedora|rhel|almalinux) + yum_repo="$DOWNLOAD_URL/linux/centos/$REPO_FILE" if ! curl -Ifs "$yum_repo" > /dev/null; then echo "Error: Unable to curl repository file $yum_repo, is it valid?" exit 1

Note: In order to overcome minor dependency conflicts with podman, buildah, and the like, I also had to issue the command


    sudo dnf -y remove runc






        

Saturday, October 24, 2020

Incompatibility of Process.waitFor() between Linux, and Windows.

 

Today, after maybe two years, I figured out, why one particular piece of code works excellent on Windows, but has been causing a lot of trouble on Linux. That piece of code is the class Executor in my Java application framework library afw.


The reason turned out to be, that the method Process.waitFor() behaves differently on Windows, and Linux, with regard to the launched processes output.


  • On Windows, the waitFor() method waits, until
    1. the launched process has terminated, and
    2. the processes standard output, and error output has been consumed (in other words: The input streams, as returned by Process.getInputStream(), and Process.getErrorStream() have been read.
This behaviour can have the unexpected result, that the waitFor() method never returns, which can easily be dealt with by simply launching two separate threads, that read those input streams.
 
  • On Linux, however
    1. The method waits, again, until the launched process has terminated, but
    2. It doesn't wait for the consumption of the processes output.
 
In other words: If you are interested in the processes output, then it is not sufficient, to invoke Process.waitFor(), because the expected output may arrive later on. Instead, you need to launch the same two threads, and then wait, until
  1. both threads have received EOF from their respective input streams, and
  2. the invocation of Process.waitFor() has returned.
That's a bit tricky, indeed.
 
In summary: Java is a highly portable platform. That being said, there might still be issues. Glad, that I could clarify this one.
 

Sunday, February 3, 2019

Announce: JSGen (Java Source Generation Framework)


It is with some pride, that I can announce JSGen today, as a new, and very minor, open source project, under the Apache Software License, 2.0

JSGen is short for Java Source Generation framework. As the name (hopefully) suggests, it is a tool for generating Java source code. It is the result of close to 20 years working on, and with Java source generation. That includes, in particular, the XML data binding framework JaxMe, its predecessor Apache JaxMe, and a lot of application programming in my professional work.

It is my opinion, that


  1. Java source generators have a tendency to grow into CLOB's over time, becoming less maintainable, and understandable.
  2. Java source generators do typically contain a real lot of boilerplate code, organizing things like import lists, and syntactical details, rather than their actual purpose.


In contrast, JSGen provides an object model, that aims to make source generation just yet another developers task, on which modern software engineering principles can be applied. JSGen will support you by


  • Creating import lists semiautomatically (with the exception of static imports)
  • Supporting multiple formatting code styles (An Eclipse-like format, the default, and an Apache-Maven-like alternative format.) Switching between code styles is as easy as replacing one configuration object with another.
  • Enabling a more structured approach to source code generation. (Example: Implement the case of handling a single instance, and use that to handle the case of a collection.)


Let's have a look at an example, which is quoted from the JUnit tests. We intend to create a simple HelloWorld.java. Here's, how we would do that with JSGen.

    JSGFactory factory = JSGFactory.create();
    Source jsb =
        factory.newSource("com.foo.myapp.Main").makePublic();
    Method mainMethod =
        jsb.newMethod("main").makePublic().makeStatic();
    mainMethod.parameter(JQName.STRING_ARRAY, "pArgs");
    mainMethod.body().line(System.class,
                           ".out.println(",
                           q("Hello, world!"), ");");
    File targetJavaDir = new File("target/generated-sources/mysrc");
    FileJavaSourceWriter fjsw = new
       FileJavaSourceWriter(targetJavaDir);
    // You might prefer MAVEN_FORMATTER in the next line.
    fjsw.setFormatter(DEFAULT_FORMATTER);
    fjsw.write(factory);

Some things I'd finally like to note:


  1. JSGen is a complete rewrite of two mature, and reliable predecessors, namely JaxMeJS, and Apache JaxMe JS. As such, it is based on a mature API, and a real lot of applied experience. It may be new, but it should be quite reliable, nevertheless.
  2. It provides all the features, of the predecessors, but adds
    1. Support for Generics
    2. Support for Annotations
    3. Switchable Code formatters
    4. Builders heavily used in the API

This announcement has intentionally been deferred until the point, where JSGen has succesfully been used for a professional project in my professional work. 

Finally, a few links:



  

Wednesday, February 24, 2016

Don't use Copy+Paste on Windows, if you've got a lot of data

Windows never ceases to disappoint me. I've got an external hard drive, on which resides a 60 GB VM, which I need to copy now and then to emulate a snapshot. So far, I used the standard Windows file copy stuff to do that. (Copy, and paste the VM directory.) Ran with about 8-20 MB per second. Or in other words: Took up to two hours. And, worst of all, the procedure isn't reentrant. Interrupting the copying means to restart.

So, tried something different: CygWin's rsync, the swiss army knife for backups, and related stuff. In other words, I am using the command

  rsync -a -r --progress
Runs with 30MB per second (50% faster than native Windows copying). And is reentrant...

Thursday, November 5, 2015

VMWare Shared Folders oin Fedora 23


Hi,

if you haven't noticed: Fedora 23 is out, and its time to get your hands wet on it. Being forced to use a Windows Laptop, I am typically doing this by installing a VMware guest. Once the virtual machine is up, the first thing i want to do is accessing my Windows home directory. The easiest way to do this is by creating a so-called "Shared Folder" in the VMware settings for my machine. On the guest, you need to install the "VMware Tools" and do something like

mkdir /home/username/sharedfolder
sudo mount -t vmhgfs -o uid=1000,gid=1000 .host:sharename /home/username/sharedfolder

(The options uid=1000,gid=1000 ensure, that the mounted directory is readable, and writable for the user with uid=1000, and gid=1000, which is me.)

The problem with that procedure is, that it depends on a kernel module called "hgfs", which must be installed as part of the "VMware Tools". And, needless to say: Installation of the VMware Tools (version 9.2.0-799703, as of this writing) fails, because the Kernel isn't compatible to the sources distributed by VMware.

So far, the only reasonable solution was to wait for an updated tools version by VMware. (I generally ignored the possibility to patch those distributed sources as overly complicated, and insecure. However, there's a new, and better solution available:

Fedora 23 automatically installs an RPM named open-vm-tools. And this includes two programs, that allow use of shared folders without the kernel module:

  # Display a list of all shared folders:
  # Note, that it includes a share called "sharedfolder".
  $ vmware-hgfsclient sharedfolder

  # Create a directory named /home/username/foo, and mount the shared folder there.
  $ vmhgfs-fuse .host:foo /home/username/sharedfolder
  $ cd /home/username/sharedfolder
  $ touch testfile
  $ rm testfile

Note, that neither "sudo" nor the specification of any options was required.

So, in other words: As of Fedora 23, the VMware Tools are no longer required. Mouse integration, Cut and Paste, and using shared folders: Everything works out of the box. (I can live without the thin print drivers.)