We have a multi-project build with the following structure:
– mainProject/heldenleben/src/
– mainProject/eulenspiegel/src/

The files in mainProject/eulenspiegel/src/main are built with a standard Gradle task and consumed in mainProject/heldenleben/src/main.

However, let’s say we needed to take the file mainProject/eulenspiegel/src/test/testHelper.kt and make it available for use in mainProject/eulgenspiegel/test/violinTest.kt.

There are 3 elements that need to happen:
1. mainProject/eulenspiegel/src/test/testHelper.kt needs to be compiled to Java bytecode
2. mainProject/eulenspiegel/src/test/testHelper.kt needs to be packaged into a jar file
3. mainProject/heldenleben/src/test needs to find and use the file created in step 2

Let’s look at each step.

1. Compile to Java bytecode
Before files are packaged into jars, they first need to be compiled to bytecode. In our case, we want to compile mainProject/eulenspiegel/src/test/testHelper.kt. Compilation should produce the corresponding classfile at mainProject/eulenspiegel/build/classes/kotlin/test/testHelper.class.

One way to do this is manually, by running the pre-defined testClasses task. However, we can combine it with step 2!

2. Package into jar file
The following code sample written in Kotlin DSL and found in mainProject/eulenspiegel/build.gradle.kts, will compile our source code and package it into a jar file. Let’s step through it.

1 tasks.getByName("assemble").dependsOn("testJar")
3 tasks.register<Jar>("testJar") {
4     archiveFileName.set("eulenspiegel-testHelpers-$version.jar")
5     include("com/eulenspiegel/helpers/*") 
6     from(project.the<SourceSetContainer>()["test"].output)
7 }

Line 1 tells Gradle’s default assemble task to wait for this testJar task that we are defining on line 3. Without line 1, assemble will not fail but it will not produce the testJar output. (You can run the testJar task manually – find it under other/testJar – but then you’d have to add it everywhere assemble is used so much better to just make assemble depend on the testJar.)

Line 3 registers a task of type <Jar> with the name “testJar” – the name is a string and can be whatever you like.

Line 4 sets the name of the archive (jar) file that we are going to produce. $version is a variable created elsewhere in the build.gradle.kts.

Line 5 is optional – in this case, we only want to include a single file. Leave blank to include everything in mainProject/eulenspiegel/src/test.

Line 6 tells us to use the standard source set located at mainProject/eulenspiegel/src/test.

3. Tell mainProject/heldenleben to use our jar file
The relevant sections of mainProject/heldenleben/build.gradle.kts are below. Let’s step through them.

1 tasks.getByName("compileTestKotlin").dependsOn(":eulenspiegel:testJar")
3 repositories {
4     flatDir {
5         dirs("${buildDir.absolutePath.replace("heldenleben", "eulenspiegel")}/libs")
6     }
7 }
8 dependencies {
9     testImplementation("com.mainProject:eulenspiegel-testHelpers:$version")
10 }

Line 1: the standard compileTestKotlin task needs to wait for our testJar task to finish, or it will fail. (And beware – this is likely something that will be caught on CI because you’ll have a local file hanging around in mainProject/eulenspiegel/build/libs that mainProject/heldenleben can find.)

Line 3: by default, Gradle will look remotely for your dependencies. These lines tell it to look for local files.

Line 5: By default, Gradle will look in mainProject/heldenleben/build/libs for the jar file. We need to tell it to look in mainProject/eulenspiegel/build/libs instead.

Line 9: this is the line that actually creates the dependency!

Good luck with your Gradle builds and comment with your thoughts 🙂

Yesterday I had the sheepish* experience of spending a couple hours trying to work out why the code I had committed in a working state suddenly stopped working. So I thought I’d write a blog post about how to debug this mysterious situation! While some of these scenarios are less likely to happen in local development, they can definitely happen in production, so if, like me, you believe in “You build it, you run it”, this can help debugging the live site as well!

What happened to me?
I was writing code to manipulate MS Word documents. I had automated tests that checked the XML of the MS Word, but for sanity, I had a local output for the file so I could open it and visually check it. I committed my changes in a working state, went to lunch, and came back and…the tests were all green but the output file was missing the changes. I tried a bunch of things that had previously caused weirdness with MS Word (hint: MS Word is really tricky to work with), ranging from invalidating my IDE’s cache, killing all the gradle processes, wiping the output folder, and a lot of swearing. I eventually realised the problem was that I was using parameterised tests, but not parameterising the NAME of the file I was outputting…so it was overwritten with each test run, and the last run had an empty input which (correctly) resulted in no change to the MS Word document. Cue more swearing.

So let’s talk about times when things mysteriously don’t work, and what some of the causes can be.

Cause 1 – external files
If you are working with input or output files, here are some questions you can ask:
– If reading from an input file, has the file been saved before being read?
– How is the output file being named?
– Is the output file path exactly what I am expecting it to be?
– Can the data in this output file be modified by another process (check out concurrency control)?

Cause 2 – software versions
I once worked in a company with a couple different codebases, each one of which used a different Node version. If you forgot to switch the Node version, you’d get weird errors (hint: there is a way to automatically switch versions on *nix – check out .nvmrc). Some questions you can ask:
– Could switching directories cause my current software version to be incorrect?
– Does this code depend on an external dependency which may have changed its version?

Cause 3 – build issues
Your code probably relies on some built dependencies. Some questions you can ask:
– Are all the dependencies built and where I expect them to be?
– Can I verify that each step of the build process is working as expected (implicit: do I know each step of the build process)?
– Is something interfering with my build process?

Cause 4 – asynchronous issues
I recently wrote a test that reliably failed every other time it was run. The problem? Part of the test relied on an unzipping process that was a bit slower – so by the time the assertions were run, the unzipping hadn’t been finished yet and the input files weren’t present. I ran a cleanup process to delete the files, but the files weren’t present by the time that was run either – so they hung around for the next test run. Some questions you can ask yourself:
– Is there any part of this process that will take longer than other parts?
– Could the capability of my operating system / hardware be slowed by some other process?
– If my tests rely on an external connection, is the network down?
– Is a remote server down?

And when none of these questions leads you anywhere, I have also found copious amounts of swearing usually do the trick…as long as I leave it for a few hours and come back to it.

*Extending the definition of sheepish to mean “something which cases me to feel sheepish” as “sheepifying” just feels so wrong.

If you’re a musician turned coder, you will doubtless be thinking about how to get that first developer job. Networking in the developer world is very different to classical music networking, so here’s a quick introduction to relationship-building (aka networking) in the software industry.

  1. Rock Your LinkedIn Profile

LinkedIn is HUGELY important — I got my 2nd developer job because I had a good LinkedIn presence and a recruiter I really liked reached out to me (shout out to Alex, if you’re reading this!). So here’s what you should do:

a) Look at these examples of career changers’ LinkedIn profiles

Paula Muldoon
Jaycee Cheong
Howard Reith
Peter Dodds

b) Add the following to your LinkedIn profile:
– picture (can use one of your musician headshots, although potentially without an instrument if you’re just starting out)
– make a headline (example: “International musician turned coder”)
– “About” section. This is your chance to tell your story about why you learned to code and what skills your previous life as a musician you can transfer.

2. Go to meetups/virtual conferences
Developers love to get together and chat after work. Go to meetup.com, find a meetup that’s relevant to you, join, and start chatting! Ruby meetups generally are beginner-friendly. Software Crafters is a good one as well. And lots of conferences are not only online right now, but you can watch conference talks from previous years any time for free. Not sure where to start? Try Brighton Ruby — they have Ruby-specific talks as well as general programming ones, they’re a friendly group, and the speakers are AWESOME. Check out Katrina Owen’s Cultivating Instinct talk. And oh yea, she’s a musician too.

3. Add people on LinkedIn
Your goal is to get to the magical number of 500 connections, at which point your profile says 500+ connections and you look like somebody that people want to know.

a) Add everyone from MusiCoders that you’ve interacted with
b) Add everyone from your software bootcamp, including teachers
c) Add everyone you interact with at software meetups
d) Add conference speakers whose talks you like, usually with a message “Hey, I saw your talk ____ and I really liked it because of ____.” They will probably accept, and if they don’t, it really doesn’t matter.

4. Rock your Twitter profile

Twitter is where the dev world socialises. And also posts jobs. We don’t use Facebook (I know, it’s weird). The good news is rocking your Twitter is less work than your LinkedIn profile. And while I haven’t yet found a job via Twitter, I have gotten an expenses-paid speaking engagement in Madrid. (Which is less exciting for us touring musicians, I know, but is a great think to put on a developer CV.)
a) Open a Twitter profile
b) Follow me (@FiddlersCode) and look at the devs I follow and follow them (at some point I’ll try to write a list of who to follow)
c) Follow the MusiCoders devs (especially @MathiasVerraes)
d) Follow #CodeNewbie

5. MusiCoders

This is your tribe — the people you have SO MUCH in common with. Join the #careers channel, and ask for support, advice, and introductions.

Not sure what MusiCoders is? Find out here.

Thanks for reading, and good luck job hunting!

Whenever I’m stuck on a coding problem, my instinct is to turn to my (senior developer) partner, gesture at the screen, flail at the keyboard and say, ‘Make it work!’

Needless to say, this approach (and yes, I have tried it), does not work.

Knowing how to ask for programming help is a really tricky skill for beginners. For us musicians, we are used to individual lessons where a teacher knows us and our context very well. These teachers often tell us what we need help with and don’t leave space for us to self-direct.

So here’s a basic template (adapt as needed with experience) that you can use to ask for help.

What language and version are you using?

Where/how are you trying to run this code? (E.g. in the browser console, the command line, an interactive shell)

Which operating system (macOS, Windows, Linux) or browser if you’re running it in the browser (Chrome, Firefox, Safari etc) are you using?

What is the context? (E.g. this is a single function or it’s the final stage in a complex web app request or it’s an automated test.)

What is the expected output?

What is the actual output?

What have you tried so far to fix it? (It really helps to keep a record of this. I use a bullet journal.)

What is the critical thing you are trying to do? (E.g. select a random number, receive a 200 status response.)

Which method(s) is/are you using to achieve this thing?

Send code snippets / screenshots!

Send code snippets / screenshots!
Send code snippets / screenshots!

Quite often by the time you have answered all these questions, you will have solved the problem. Not all of it will be relevant to your specific problem but it’s good to know anyway! And if you haven’t solved your problem, this gives someone else really useful information to help you.

Got other questions to include? Let me know in the comments!

JavaScript edition:
Have you forgotten to include a return statement?

Photo credit: Jemima Willcox

My name is Paula Muldoon, and I’m a highly trained classical violinist. I have a B.M. (from the University of Michigan) and an M.M (from the Guildhall in London). I’ve recorded in Abbey Road, I’ve performed in Carnegie Hall, and I’ve played in four continents. I’ve been a member of the Orchestre Révolutionnaire et Romantique and the Royal Liverpool Philharmonic Orchestra, and I’ve played with the London Symphony Orchestra and the Philharmonia Orchestra. I’m currently the leader of the Cambridge Philharmonic and the Cambridge String Quartet.

For the past three years, I have also held a full-time job as a software engineer. And in this post, I’m going to tell you why I think you should too.

1. Salary

I’ve been a freelance musician in both the USA and the UK and I hope I never take for granted the unbelievable security of having the same amount of money deposited in my bank account every month. I earned more money as a junior developer in my first job than I ever did as a violinist. And I’ve had roughly a 10% increase in each of my jobs. Plus with salary comes a much easier ability to take out a mortgage. I can’t state what a diffence a regular salary has made to my quality of life, especially to my mental health. (Hey, I can now afford therapy!)

2. Pension

I always said pension was something I’d worry about when I turned 30. Then I turned 30 and became a software engineer, and now I have a tax-efficient, employer-contributed pension. UK law requires employers to contribute at least 3% and employees at least 5% of their salaries to a pension. Yes, I started saving about 8 years later than most employees, but with 35 years of a working life left and an aggressive savings plan now, I am confident I’ll be able to retire comfortably.

Photo credit: Jemima Willcox

3. Healthcare

Less relevant in the UK, but if you live in a barbaric country that doesn’t regard healthcare as a basic human right, this could literally be life-saving. I still remember the time I got a $600 bill after going to the ER in the USA for a strep throat test shortly after I got off my parents’ health insurance. With insurance? No problem. Without? I spent six months paying off that bill. And I didn’t even have strep throat.

4. Holiday/Vacation days

I have 30 days of holiday (plus 8 public holidays). Now I work for a German company, so this is more generous than my UK jobs, which were usually 25 days plus public holidays. Even in the USA, you will still get some holiday! This means you can recharge, rest, go somewhere WITHOUT THE VIOLIN (or whatever your instrument is). It’s taken me 3 years, but I’m finally able to take a violin-free vacation without the feeling I should be practising.

5. Coding is fun

OK, enough with the boring practicalities. Coding is a lot of fun. You can work on all sorts of problems — so far, I have sold shoes online, developed cognitive assessment tests used in clinical trials, and now work in legal tech. Is there an area of the world you care about? You can code there. I actually had no idea whether I would like code before I became a programmer — I just really needed financial stability. Turns out coding is SO MUCH FUN.

Photo credit: Jemima Willcox

6. Musicians have lots of transferable skills

Communication skills, teamwork, analytical minds, desire for excellence, strong work habits.

7. Music can be even more rewarding

I still play lots of music, and I now enjoy it so much more. Everything I do is on my own terms, which means that I turn up for rehearsals and concerts where I want to be there — it’s not for the paycheck.

8. You can still be a professional musician

Lots of programmers have side hustles. Often they are a small code-based business but sometimes they are music! So I have a nice side-income in violin playing / teaching that I love doing (see above) and am in no way dependent on the income. So yes, with Covid-19 I lost a lot of income, but I still have my programming job and just slightly less disposable income (oh yea, you get disposable income).

Photo credit: Jemima Willcox

9. Ethical Considerations

The software industry has a huge issue with lack of diversity, which leads to serious ethical issues — think algorithms that perversely punish people of colour. Musicians bring a tremendously fresh perspective and a mindset geared toward understanding and cooperation. You can make a real difference in the world by coding.

10. It’s not selling out — it’s creating a new path

People look down on musicians who take a day job. I’m calling b*llsh*t on this. Classical music has a very narrow definition of success, which results in many music grads living a financially perilous existence in exchange for the perceived glory of being on stage with a great ensemble. The financial freedom a day job gives allows artists space to be more creative. We need to redefine being a professional musician so that it includes people with all sorts of income rather than stigmatising them as “sell-outs” or “not good enough”.

Hopefully this has given you some food for thought. If you’re a musician considering a career change, check out the resources on my website https://paulamuldoon.com/resources-for-new-programmers/ and get in touch — I’m happy to chat with you.

We’re at a sweet spot now where the demand for programmers still massively outweighs the supply. It’s also the only career where you can train in 3 months and get a full-time well-paid job. If you’re thinking of becoming a software engineer, now is definitely the time to do it. Good luck!

Photo credit: Jemima Willcox