Blog

  • Solving Newlines in MySQL TO_BASE64()

    How to remove unwanted line breaks in Base64 output

    When working with binary data in MySQL- such as certificates, keys, or other BLOB content-the TO_BASE64() function is the easiest way to export binary values in a portable text format.
    But many developers run into an annoying detail:

    MySQL automatically inserts newlines into the Base64 output.

    This can break APIs, JSON output, or scripts that expect Base64 to be a single continuous line. In this article, we’ll look at why this happens and how to reliably remove these unwanted newlines.

    Why MySQL inserts newlines in TO_BASE64()

    MySQL follows the MIME Base-64 specification RFC-2045. This standard requires that each encoded line must be no longer than 76 characters. Because of this, MySQL inserts a newline every 76 characters in the Base64-encoded string.

    This made sense historically, e.g. for email compatibility, but in modern applications it often creates more problems than it solves.

    The problem in practice

    Example:

    SELECT TO_BASE64(certificate)
    FROM distributor
    WHERE name = 'ACME';

    Instead of one long Base64 line, the output may look like:

    MIID5TCCA8+gAwIBAgIQB3h1g/...
    ui83iFkV103ef28hiUIgUGuiA/...
    g93kP6a1Dq7rzsQ==

    Those newlines are part of the actual string—not just formatting in the client.

    The solution: Remove newlines from Base64

    MySQL does not offer an option like “NO LINE BREAKS”.
    However, there’s a simple and reliable alternative solution:

    SELECT REPLACE(REPLACE(TO_BASE64(certificate), '\n', ''), '\r', '')
    FROM distributor
    WHERE name = 'ACME';

    This reliably strips out all MySQL-inserted line breaks and returns a clean, single-line Base64 value.

    What makes the solution great?

    It

    • works in all MySQL versions
    • is fast and lightweight (REPLACE() is very efficient)
    • ensures that all MIME-style breaks are removed
    • preserves the original BLOB unchanged
    • works equally with Unix and windows newlines

    These points make it a nice workaround that can be used in scripts, backends, and export pipelines.

    Conclusion

    If you export binary data like certificates from MySQL, you will eventually run into that nasty issue, but don’t be afraid,
    the fix is simple:

    Strip newlines using REPLACE() and you’re good to go.

    You get a clean, single-line Base64 string that plays nicely with JSON, APIs, and configuration files.

    So long, thanks for reading and have a great day.

    I got your mouth wet for more certificate fun and SSL? This post is about setting up HTTPS for Maven. And adventure by itself. Or if you’d rather like to see something different? Here’s some testautomation fun with Rust.

    Share it with:
  • Python Child Processes and subprocess run

    If Python likes to do except for KI and prey on mice it is automation. Test automation, process automation, tiny little helper supporting finance people all over the world… automation is on everyone’s lips – and on everyone’s project schedules. And due to the nature of automation in fields other than regular software development we might want to use what the operating system is already providing us. That’s where subprocess run comes in handy to create child processes in no time. We will see how to start an external child process from within python and we will use it to implement a simple automation use case. Let’s-a-go.

    Quick child process sample with subprocess run

    Okay let’s not go that fast. Before we head into the real thing, let’s train with a simple example. We will let the OS print the today’s date through a Python child pocess. Please see the following listing:

    Execute that code in your favorite console or IDE. You should get an output line similar to this:

    Sun Mar 9 19:01:22 CET 2025

    The first parameter is pretty straight forward. We provide the run method with the program command we would like to start using the list notation – date in this case. Another popular example could be ["ls", "-al"]. Try it out by replacing the date command with that one. In the meantime I tell you what the other method parameters do.

    capture_output=True

    This makes sure that we save the output in process.stdout for later use instead of just firing the command and forgetting the output. That would be kinda not-handy when we automate more complex things.

    encoding=“UTF-8″

    Without setting a nice string encoding we would get a byte-representation of process.stdout when printing that to the console. That’s not nice. Therefore we set the encoding to UTF-8 and get a nice and clean output line.

    Advanced automation example: Create an X509 certificate using child processes

    Alright, now that we a warmed up we will tackle a more realworld automation example. Let’s imagine you are tasked to secure a Maven repository with TLS and you need to generate an X509 certificate. If you are an avid reader of my blog this might sound familiar to you and you are right! Just recently I posted about SSL/TLS for Maven repos where we generate a Java Keystore and use that to connect to a repo via HTTPS. For this post here we take the certificate generation shell script and execute that from python. Let’s see how we achieve that:

    Execute that in a separate .py file in your favorite IDE and you should receive a neat set of X509 files including our target: endUser.crt.

    My favorite method options for subprocess run

    Now we got to know capture_output and encoding already. What else does subprocess run support? Here are 3 of my favorite method parameters:

    check

    If this is set to True and the child process terminates with a non-zero exit code – i.e. terminates with an error – a CalledProcessError is thrown. If False the process just terminates and your program will go on as if nothing happened. I am a big fan of failing fast so this is big sugar to me.

    shell

    If set to True your child process can use advanced shell features like pipes and filename wildcards. This is especially useful when it comes to various IT automation tasks.

    env

    This takes a str-to-str-dictionary containing your personal custom set of environment variables tailored to your child process by you. This set overrides the default set that is derived from its parent. This comes in handy if you want to start your process in a more isolated way.

    You are curious and want more now? Feel free to check the Python subprocess docs. There you’ll be served.

    Final thoughts

    Phew! Now we definitely earned our after-work soda. We have seen what the subprocess run – method is capable of and we solved real-world problems using child processes provided by that. We got ready to automate aaall the things that’s for sure. Wait, you still want more automation with Python? If you really do and you are willing to dip into software testing I have one to offer that covers test automation in Python. Alas it’s automation, too. Right? Or did you think that Python is not your thing now but you got inspired and want more shell? That’s perfectly fine, too. Here we create Linux users directly in your favorite shell.

    Share it with:
  • Docker Compose: Custom Commands to Keep your Container up

    Sometimes you just want to keep up your container without running the intended process, for example to diagnose an unexpected shutdown during starting up the container’s process. To achieve that, we make use of the option in docker and docker-compose to overwrite the container’s innate command that is usually executed during your container’s runtime.

    Preparing our experiment

    First of all we gotta pull the docker image for our experiments. For illustration purposes we use an image that is completely unrelated to any command we’re going to use later:

    docker pull maven:3.9.9-eclipse-temurin-8-alpine

    That’s all. Now let’s head into our experiments.

    docker container run COMMAND – parameter

    When executing docker run we can not only set an image name but also add a custom command that overrides the image’s default command. Let me illustrate that by showing you the date of today as of writing this post – using maven’s docker image.

    >docker run maven:3.9.9-eclipse-temurin-8-alpine date
    Sat Mar 8 14:21:43 UTC 2025

    where maven:3.9.9-eclipse-temurin-8-alpine is the docker image and date the custom command that replaces the default mvn execution.

    docker compose directive – command:

    Being a decorator on top of docker’s base CLI docker compose can do anything that plain docker run can do. Thus we can do custom command executions here as well. In fact, it’s much more fun than using the default CLI. But thats just me. Now without further ado:

    And there is our today’s date.

    What commands can we use in docker?

    In this section I present my favorite commands to keep my docker containers open. The most intuitive is probably:

    sleep infinity

    That one is pretty self-explanatory. We just sleep for an infinite amount of time or until we manually cancel the process. The constant infinity is defined in the GNU world and serves us as a representation of positive infinity.

    The next one is:

    top

    We just let your container dispay it’s realtime ressource usage thus keeping your container up and running. Time to docker exec into it and do our thing. Little caveat: Some images may strike top out to reduce the container’s size and to focus on it’s core business. If that’s the case, we should try my top-most favorite. This one should be available quite often and looks so cool:

    tail -f /dev/null

    That one waits on a neverending file and tries to spit out whatever it finds at the end of it – in this case dark and pure nothingness.

    Final thoughts

    This post was a personal matter of heart to me having had the use case several times. But since im getting old *sigh* I tended to forget what commands I can use. Now that’s finally a thing of the past. Give it a bookmark and it will keep reminding you as well. Do you have a favorite command to keep things up? Feel free to drop me a line in the comments down below. And if you still can’t get enough of Docker or Maven here are some recommendations just for you: My most recent star is this post about configuring TLS for HTTPS-secured Maven repos. And finally for the more docker-inclined people out there this post about docker ps – formatting might make your daily life a little simpler.

    Have a sunny day!

    Share it with:
  • Problem reading geckodriver versions: error sending request for url

    Today, while hunting down a nasty issue in a longer Selenium/Cukes scenario outline, I was flooded with a particular annoying warning:

    WARNING:
    org.openqa.selenium.manager.SeleniumManagerlambda$runCommand$1
    Problem reading geckodriver versions: error sending request for
    url (https://raw.githubusercontent.com/SeleniumHQ/selenium/trunk/common/geckodriver/geckodriversupport.json).
    Using latest geckodriver version

    org.openga.selenium.manager.SeleniumManagerlambda$runCommand$1
    WARNING: Exception managing firefox: error sending request for
    url (https://github.com/mozilla/geckodriver/releases/latest)

    You too? Then you are at the right place.

    The reason

    Selenium is trying to check for an update for your geckodriver executable. What is planned as a nice convenience feature can be quite an annoyance in a restricted environment. When Selenium is executed within such an environment, it cannot contact the remote geckodriver version dictionary and nags us with „Problem reading geckodriver versions: error sending request for url …“.

    Thankfully the Selenium team seems to be aware of that and provided us with a simple fix. Sadly that fix is quite non-explicit but that’s not going to stop us anytime soon.

    Fixing the „Problem reading geckodriver versions: error sending request for url“ warning

    The update check happens if – and only if – Selenium derives the geckodriver path from Seleniums automatic lookup feature (i.e. when it checks the system PATH variable). Therefore all we have to do is setting the geckodriver path explicitly. In Java we do that like this:

    By setting that Java system property we tell Selenium explicitly what geckodriver to use and we prevent it from doing any additional shenanigans on the driver binary thus silencing the warning. Using an appropriate if-clause you can tailor it to any kind of environment. You have full internet access? Cool! Then your system geckodriver might be perfectly sufficient. It’s all in your hands.

    Final thoughts

    Alright! This should relieve you from that „Problem reading geckodriver versions: error sending request for url“ warning. When working with complex Selenium Webdriver tests, it is overall nice that the framework logs so verbose and provides us with all these features. But sometimes it can be a little full of itself. The good thing is though that there usually is a way to customise Selenium’s behavior to our personal needs, whether it is working in a restricted network area or with full access to the internet – Selenium knows it all.

    Though sometimes it has its difficulties to articulate itself – just as we humans do. Anyways, thank you for reading. If you are still curious about what’s possible with Java in QA, here’s an interesting post about fuzzing in Java. If you don’t particularly care about Java but you would like to see more test automation action in general, I’d recommend trying Cucumber in Rust.

    Have a great day!

    Share it with:
  • java.sql.SQLException: Before start of result set

    In the world of Java development, working with databases is a common task, and JDBC (Java Database Connectivity) is the standard way to interact with databases in Java applications. However, it’s not uncommon to encounter errors along the way, one of which is the java.sql.SQLException: Before start of result set. This error can be a source of confusion for many developers, especially those who are new to working with JDBC. In this post, we’ll dive deep into what causes this exception, how to fix it, and best practices to avoid it.

    What is the „Before start of result set“ Exception?

    When working with JDBC, the java.sql.SQLException: Before start of result set – error occurs when you try to access the data in a ResultSet before the cursor is properly positioned. In simpler terms, this means that you’ve tried to read data from a result set before calling the necessary methods to move the cursor to the correct position.

    The Cursor in JDBC: A Quick Overview

    When you execute a query in JDBC, the result is stored in a ResultSet. This ResultSet can be thought of as a table of data that comes from your database. The cursor is essentially a pointer that allows you to navigate through the rows in this table. By default, the cursor starts before the first row of the ResultSet, meaning it hasn’t been moved to any row yet.

    To access the data in the ResultSet, you need to move the cursor to a valid position using methods like:

    • next(): Moves the cursor to the next row.
    • previous(): Moves the cursor to the previous row (only if the ResultSet type allows backward navigation).
    • first(): Moves the cursor to the first row.
    • last(): Moves the cursor to the last row.

    If you attempt to read data without moving the cursor, you’ll encounter the „Before start of result set“ error.

    Common Causes of the Exception

    Here are some of the most common scenarios that lead to the java.sql.SQLException: Before start of result set exception:

    1. Accessing Data Before Calling next()

    The most common reason for this error is that developers forget to call next() before accessing data. The next() method moves the cursor to the first row, and you can only start accessing data after this method returns true.

    Example of Incorrect Code:

    Corrected Version:

    2. Empty Result Set

    Another cause could be that the ResultSet is empty. In this case, calling next() will return false, and any attempt to access data after that will result in an exception.

    Solution: Always check if the ResultSet has data before accessing it.

    3. Navigating the Cursor Incorrectly

    If you are using a scrollable ResultSet (e.g., TYPE_SCROLL_INSENSITIVE or TYPE_SCROLL_SENSITIVE), it’s possible to move the cursor to an invalid position (like before the first row or after the last row).

    Example:

    Solution: Ensure the cursor is in a valid position using navigation methods like next(), first(), or last().

    How to Fix the „Before start of result set“ Exception

    Here are the steps to fix and avoid the java.sql.SQLException: Before start of result set:

    1. Always Use next() First

    Before accessing any data in a ResultSet, always use the next() method to ensure the cursor is pointing to a valid row:

    2. Check if the Result Set is Empty

    To handle the scenario where a ResultSet might be empty, you can use an if check:

    3. Understand Result Set Types

    If you need to navigate backward or perform other complex navigation, use the appropriate ResultSet type:

    4. Logging and Debugging

    Add proper logging and debug statements to understand the flow of your code when dealing with ResultSet. This can help you identify if you’re trying to access data at an invalid cursor position.

    Best Practices for Working with JDBC Result Sets

    • Check for an empty ResultSet before attempting to iterate.
    • Use the correct ResultSet type if you need complex navigation.
    • Close the ResultSet, Statement, and Connection objects in a finally block or use a try-with-resources statement to avoid resource leaks.
    • Add logging to catch potential issues early, especially when navigating through ResultSet.

    Conclusion

    The java.sql.SQLException: Before start of result set error is a common pitfall for Java developers working with JDBC. However, understanding how the cursor behaves and correctly managing it can help you avoid this exception. Always ensure that you move the cursor to a valid position using next() or other navigation methods before accessing data in the ResultSet. By following best practices and debugging carefully, you can handle this exception effectively and build more robust database-driven applications.

    So long! If you like this post I have a few others for you. If you like testing – which is my main passion – here is one, where I introduce you to test automation with Selenium JVM. Or if you’d rather like to cause some chaos, here is one about fuzztesting – a fun testing technique that brings your code to the knees. Have a great day!

    Share it with:
  • Maven SSL and HTTPS Configuration – a Howto

    In the world of Java development, working with Maven repositories is essential, as these repositories host the dependencies that our applications rely on. While connecting to public repositories like Maven Central is straightforward, accessing private or secured Maven repositories requires additional configuration. Specifically, when connecting over HTTPS, a Java Keystore may need to be configured to trust the repository’s SSL certificate. Here’s how to set up a Java Keystore for secure HTTPS connections to a Maven repository, ensuring a seamless and secure build process.

    Why configure a keystore?

    Java applications, including Maven, use the Java Keystore (JKS) to manage certificates for secure communication over SSL/TLS. If your Maven repository uses HTTPS with a self-signed or non-standard certificate, Maven might reject the connection because it cannot verify the certificate’s authenticity. By adding the repository’s certificate to a trusted keystore, you’re explicitly telling Java and Maven to trust this certificate. This setup is particularly relevant for organizations using internal repositories or third-party vendors with their own certificate infrastructure.

    Create a test certificate chain

    At first we build a custom certificate for test purposes. Please see the following few lines of bash:

    Create a Java Keystore (JKS) from certificate and key

    Next we build the JKS file from our new certificate and key:

    Set up and use Maven’s .mvnrc file

    Configuring SSL for Maven using a .mavenrc file may look familiar to you as it involves setting up environment variables for your Java KeyStore (JKS) settings:

    Put the file somewhere where your shell is able to consume it or run

    $ source /path/to/your/.mavenrc

    yourself to have your SSL config up and running.

    Configure .mvn/jvm.config file for Maven SSL Authentication

    A .mvn/jvm.config keeps your project well-structured with regards to separation of concern and allows for an easy Maven SSL configuration. Therefore this is the way I recommend. To use it properly create a .mvn directory in your Maven project’s root directory, put it on .gitignore (or an equivalent file depending on your VCS) and place a file jvm.config in there. Here we place our Maven SSL config like this:

    Use the Maven settings.xml for SSL config

    If you prefer to have the whole authentication process at one place there’s always the settings.xml for you:

    Benefits of a custom keystore configuration

    Setting up a custom keystore for Maven offers flexibility and security. It enables secure connections to internal repositories or those requiring special certificates, without affecting the global Java truststore. Additionally, it simplifies management when dealing with multiple repositories or environments, as each project or CI/CD pipeline can use its own keystore as needed.

    Final Thoughts

    While configuring a Java Keystore may seem daunting, it’s a powerful way to manage secure connections to Maven repositories. By following these steps, you can ensure that your Java applications are securely retrieving dependencies, protecting your codebase and development environment from potential threats. So next time you encounter an SSL error connecting to a repository, remember—it might just be a keystore configuration away from a quick fix! The full CA and JKS script can be found in this gist, and if you are not fed up with Java, here’s an interesting post covering Browser Test Automation in Java. If you’d rather see something else, don’t worry, here’s the Python version. One more I’d like to share with you: Fresh from the oven comes a post, where I explain the SQLException „before start of resultset“. Give it a click and and see you next time!

    Share it with:
  • Gitlab CI Error – Cannot create local repository at: /.m2/repository

    When you are using downstream pipelines in Gitlab CI for complex Maven Projects as I do, you may have stumbled accross this error at least once: Cannot create local repository at: /.m2/repository. The Gitlab runner tries to create a local Maven repository at /.m2/repository – so in the topmost directory – and fails horribly due to an obvious lack of permissions. Let‘ see what happens here.

    The Gitlab CI Setup

    In my case I had a shell-based Gitlab runner that executes a test suite based on a few artifacts published by a Docker runner. Due to versioning and system test level realism reasons I was not able to use the artifacts directly. Unfortunate, but it shouldn’t pose that kind of a problem, does it?

    Now when it comes to cloning the test suite on my shell runner, this cryptic error has been dropped. And naturally I was like „WTF is this runner trying to do!?“

    The root cause in Gitlab CI downstream jobs

    What I was not aware of is that per default the „child job“ inherits all the custom and Gitlab-provided runner variables from the triggering parent job that is still executed on a Docker runner. Now since the trigger happens from a Docker runner job, the variables my child job receives are poison for a baremetal environment that is my shell runner. Not least because things actually do happen at / in a Docker-based Gitlab execution environment, which is perfectly fine, but not on a shell runner.

    The solution: What I had to do to make the CI jobs work

    To fix the problem I had to set this on my trigger job definition:

    This did not just fix the error for me, but it also made perfect sense. Due to the different execution environments – shell vs. docker and project A vs. project B – I have a different set of requirements for my Gitlab CI test job. Therefore we have another case of an error leading to better software design. In addition I learned another piece of Gitlab’s sometimes quite obscure default settings.

    Conclusion

    I hope this helps you during your day to day journey through the jungle that are Gitlab CI downstream jobs. As I’m an avid QA engineer, so if you want to read more about writing actual automated tests. Also I take care of deeper coding basics like working with threads in java. If you’d rather want to read up about Gitlab CI’s inherit keyword, here’s the link to the relevant section of the official Gitlab CI documentation. Feel free to have a look!

    Have a great weekend everybody!

    Share it with:
  • Java Threads – an Introduction for all Skill Levels

    Today we are talking about threads in Java. Threads are an essential means to implement concurrent algorithms and are therefore a key part of efficient everyday data processing. Imagine having a webserver without threads serving only one customer at a time: Every customer would need to pull a number for every single web request they make and our online shop would have a bad time.

    So let’s head into it!

    In modern days – Java threads with Lambda expressions

    Since Java 8 we have been blessed with Lambda expression. Basically Lambda expressions serve the purpose of unnamed functions and are written as shown here:

    (param1, param2, [...], paramN) -> {
        statement1; 
        statement2;
        [...]
        statementN;
    }

    If you just need one statement, it looks even better:

    (param1, [...], paramN) -> statement

    By harnessing their power we are able to write beautiful first level function style concurrent algorithms.

    Let’s assume we want to sort a list with an even number of integers. We know that all ints in the second half of the list are greater than the greates number in the first half. Then we can do this:

    Try it out!

    Notice that we feed the threads in our Java code with Lambdas to tell them what to do. Neat, isn’t it?

    Legacy Java Threads with Runnable instances

    And how has it been done in the past? When I started programming with Java around 5 and 6 we had to declare a full-blown Runnable-instance that we subsequently fed to the thread. Runnable is an interface type which means that during declaration we also had to implement it’s signature method run(). This method finally contains the functionality that the thread is supposed to run. Let me show what I mean:

    Try it out!

    It was a bloated mess, but since it’s likely in use in modern day code, we got to list it here.

    Released in Java 21: Virtual Threads

    Virtual threads are part of Project Loom that aims at bringing lightweight and high-throughput concurrency models to the JVM. These virtual threads don’t run on kernel but on JVM level and thus are fully managed by the JVM. That means you as the coder do not need to keep track of them at all. The JVM will do that for you while you can rely on the coding APIs you already know and love. That is because virtual threads are created almost the same way as the native threads we have seen earlier. Let me show what I mean:

    As shown above you the virtual threads API hands you a Thread instance that you can use in ways you are already familiar with. Here we wait for our virtual threads to terminate.

    Another important advantage over conventional threads is their ability to scale. Since the JVM manages both ressources and lifetime of virtual threads it is done in a thoroughly optimized way. In addition, because these threads run directly in the JVM instead of the OS kernel, we can omit a lot of OS ressource management overhead. Both factors result in a significant increase of throughput.

    Conclusion

    So long. I hope I could help you effectively processing data by leveraging the power of Java threads. Please note that the examples shown above are optimized for the topic’s illustration only. Your way to sort a list of integers is certainly much better. If you’d like to read more about me doing Java, I have a post for you, where I talk about web test automation with Java. If you are already familiar with that and want to try something new, I recommend trying fuzz testing in Java. You will gain a fresh view on test automation and honestly it’s a blast to bomb an application with just random stuff.

    Last but not least, if you want to dive in really deep into the world of Java threads, check out this article about Thread Pooling. It is quite advanced, but intuitive and powerful once you get the hang of it.

    You have more questions regarding Java, me or anything else? As usual, feel free to drop me a line down below. I read every single one of your comments. Have a great day!

    Home
    Share it with:
  • Character array is missing „e“ notation exponential mark

    In my previous article about Fuzzing in Java, I encountered an interesting NumberFormatException: „Character array is missing „e“ notation exponential mark“. That one sparked a lot of curiosity. Today, let’s take a closer look at what exactly this error message means.

    What Does This NumberFormatException Mean?

    Let’s start with a simplified version of a method, dollar2euro, which converts a USD input to EUR:

    Now, suppose we call this method using the string "뤇皽" as input.
    This would produce the following error:

    Input: 뤇皽
    java.lang.NumberFormatException: Character 뤇 is neither a decimal digit number, decimal point, nor "e" notation exponential mark.

    The message tells us that the character 뤇 is neither a decimal digit, a decimal point, nor an „e“ used in exponential notation. In mathematics and programming, exponential notation expresses numbers like 1e3 to represent 1000 compactly. Java expects input strings for BigDecimal to contain only valid number representations — digits, decimal points, or the character e for exponents.

    Since „뤇“ is none of these, Java immediately throws a NumberFormatException.

    How Can You Avoid This Error?

    To prevent this error, we should ensure that the value passed to the BigDecimal constructor is a valid number.
    Ideally, you would work directly with numeric types like double or int whenever possible.

    In our method, this would only require a small change to the parameter type and the parsing logic.

    If you still prefer to work with String inputs, make sure the string represents a valid number format.
    An example of a valid input would be:

    "1337.012342

    By sticking to properly formatted input, you can avoid NumberFormatException issues like the one described here.

    One side note here: Proper validation of user input is a critical security measure recommended by OWASP to prevent injection vulnerabilities and ensure application robustness. Using and handling this exception may help you here depending on your use case.

    Conclusion

    I hope this article helped clarify what the error „Character array is missing ‚e‘ notation exponential mark“ means in Java. While today’s example was constructed for clarity, such issues often arise unexpectedly when dealing with user input or external data sources.

    If you have encountered a similar error in a real-world scenario, feel free to share it in the comments. I would be happy to take a look!

    If you’re interested in diving deeper into testing and automation, you might enjoy my tutorials on Selenium with Java and Selenium with Python.
    Or, if you want something a little more adventurous, check out my Cucumber in Rust tutorial.

    Happy testing and have a great day!

    Home
    Share it with:
  • Stable Diffusion: „LayerNormKernelImpl“ not implemented for ‚Half‘

    Today I installed the Stable Diffusion Web UI by AUTOMATIC1111 on my ol‘ reliable Macbook Pro 2015 following this stable diffusion installation guide. And not only is it fun to do AI stuffs on an Intel Mac with no GPU whatsoever, of course I also had to run into a „first try error“ ™. This time it was that one:

    RuntimeError: "LayerNormKernelImpl" not implemented for 'Half'

    Okay, cool.

    So how do we fix that?

    Well it turns out that this „half“ thingy, that relates to floating point sizes, can be turned off. To do that, let’s revisit your stable-diffusion-webui installation directory and open the shell script webui-user.sh using your most beloved code editor. Here you will find the following 2 lines:

    # Commandline arguments for webui.py, for example: export COMMANDLINE_ARGS="--medvram --opt-split-attention"
    #export COMMANDLINE_ARGS=""

    What we got to do now is: First we remove the leading ‚#‚ character of the second line to uncomment it. Next, we fill the variable with "--skip-torch-cuda-test --no-half" to make it look like this:

    export COMMANDLINE_ARGS="--skip-torch-cuda-test --no-half"

    Restart the stable diffusion web ui using your webui.sh and it should behave as expected. All of that has been tested with stable-diffusion-webui commit cf2772fab0af5573da775e7437e6acdca424f26e, which was the most recent stable version at the time of writing.

    If you are on a Windows machine, the fix should be basically the same: Open the webui-user.bat and change COMMANDLINE_ARGS to match the following:

    set COMMANDLINE_ARGS="--skip-torch-cuda-test --no-half"

    Restart your server and everything should be alright. (Disclaimer: Untested due to the lack of Windows machines.)

    Conclusion

    So that’s all, hope this helps. If not, feel free to let me know in the comments below. If you find a better fix, or my post is outdated, or you found any other issues, please let me know as well. Let’s keep it as complete as possible for future users. And if you are still curious about working with Python apps or Python in general, here is another quick and handy post about handling environment variables. And here we talk about my second most favorite topic: Test Automation.

    Best regards, and have a nice week!

    Home

    Share it with: