Beer Brewing – A Beginner’s Guide

Beer Brewing – A Beginner’s Guide

May 30

This information is readily available around the internet.  Home Brewing has become a regular pastime of tons of people in the US.  Unfortunately everyone who gets into it ends up getting really heavy into it and forgets that folks that are just learning aren’t going to understand what they are talking about.  So I thought I would put a quick cheat-sheet together for those just getting into home brewing.  If you want to learn more of the advanced concepts and techniques, please check out the brewing or homebrewing article on Wikipedia and start checking out the many blogs out there.

 

Definitions:

Yeast
A single celled fungus.  These little guys are the most important part of brewing.  Everything we do is to make them happy. Since there are different thousands of kinds of yeast (at least), it is important that you buy the yeast from a brewers supply to make sure that you get a reasonably pure batch.WortA sugary liquid extracted from the mashing process.
Malted Grains
Germinated grains (e.g. started growing) that have been dried (which stops the growing process) with hot air.Malt ExtractFor the most part, in home brewing, this refers to malted grains that have been turned into a syrup or a powder, which contains all of the sugar that your yeast should need to eat during the fermentation process.
Hops
Come in many forms, such as pellets, plugs, and fresh whole flowers.  These are a close relative to the help plant that provide resins that Impart bitterness (using alpha and beta acids) and aroma to your beer.  These are not readily water soluble.
Alpha Acid
Heat and boiling (called isomerization) allow these types of acids to become soluble in water, which is why you steep the brew.  The more alpha acid a certain type of hop contains, the more bitterness it imparts to the beer.  The amount of alpha acid is usually listed on the package of the hops.
Beta Acid
It is important to use fresh, unoxidized hops to extract the small amount of beta acids available.

Equipment

A lot of these can be bought in a kit and just add the extras on later.  My suggestion, go to your local brewery supplier.  They probably need the money and can provide you with tons of insights to any questions that you might have.

  • Pot – You have to boil the water and add things. Basically, you need a big soup pot, 5-10 gallon.
  • Spoon – You should have a really decent spoon
  • Bucket – Bucket Lid drilled for air lock
  • Bottle for Yeast (optional) – A growler or another similar bottle for the yeast starter
  • Air Lock(s) – Essentially a P-trap that lets out gasses, but doesn’t let anything in
  • Siphon – helps you transfer beer from one container to another (in a fairly sanitary way)
  • 50 non-screw top brown bottles (or one 5-gallon Cornelius Keg – for the kegerator making folks)
  • Fine strainer – For straining out particulates after fermentation is completed
  • Hydrometer – measures density, and thus sugar content (which translates to eventual alcohol content)
  • Your favorite Brew kit – something like this.

Step 1: Yeast Starter (optional)

The process of getting the yeast to start eating and reproducing so that they aren’t shocked when you throw them into the the wort. Some people skip this step by just sprinkling dry yeast into the wort at the end, but in my opinion, this is a mistake that can cause a bad batch because you might accidentally kill the yeast if your beer is a little less than optimal or you might need to wait longer until you beer will be ready.

In a pot, add one quart of filtered water and 1/2 cup of dry extract.  Boil this for about 10 minutes.  Rapid cool this using a sink of ice to about 70℉.  Pour into a sanitized bottle, add the yeast, and then shake vigorously to oxidize the solution.  Leave this to sit from anywhere from 5-24 hours.

For a nice video tutorial, watch this:

Step 2: Cleaning

Clean everything, getting all of the residual gunk off of bottles and tools.  Then sanitize the bottles and fermenting tools, either by boiling, hot air, or using a quick sanitizer.  Make sure that nothing in the wort comes into contact with anything that hasn’t been sanitized.  This is especially true after the cooling.  This is probably the most important part in the whole process, even though it is not very exciting.

Step 3: Malting & Lautering

The process of fertilizing grains, letting them start to grow, and hitting them with hot water, then separating the sugars from the grains. The more advanced home brewers will do this themselves, or at least do this in part.  For the beginner, ignore this.  You will buy a malt extract in a can (syrup) or in a bag (powder) form.  When you get better at this, you can perform what is called “all-grain” brewing.

If you really want to do this, watch this series of videos for malting Barley.  It’s a bit of an involved process.

Step 4: Mashing

This is the fun part of brewing.  Some people call this “boiling” or “steeping”.  It’s pretty much taking grains and putting them into a grain bag (aka muslin bag) and letting it steep in boiling water in the same way that you would add a tea bag to a cup of tea.  Some of the hops are also added directly to the water at this point as well to add bitterness and aroma.

So, fill a pot with about 3 gallons of water.  Add the bag of grains while the water is still cold.  Heat it up to 155℉.  Try and keep the grain bag from touching the sides of the pot, as it will burn/melt.

Keep the steeping over 150℉ and below 180℉ - the ideal conditions are to boil for 25 minutes at 155℉.  Keeping the temperature above 150℉ will break down the grain.  The type of grain you use will determine the majority of the color and flavor that is perceived. Do not exceed 180℉ – This is because if you heat it above 180℉, it will start to break down the husk of the grain.  You do not want the husks to impart their tannins into your brew.  Don’t cover the pot as sulfur compounds that are being produced need a chance to escape.

Resist squeezing the grain bag as you want to avoid imparting any tannins from the grain husks.  If you want to make sure to get all of the good stuff out of the grain bag, I suggest running a couple of cups of hot water over the grain bag to flush it out.

Adding hops in the beginning of the steeping will impart bitterness to the beer at this point.  You can control the bitterness by understanding the amount of alpha acid you will be imparting to your beer.  This is determined by the original alpha acid amount and the length of time that the hops are boiled for.  Adding hops at the end (the last 5 minutes or so) of the steeping will impart aroma.

Step 5: Wort Cooling

You want to cool down the wort as fast as possible.  This is due to the fact that the sulfur compounds are still being produced as long as the temperature is high.  These will give your beer a slight egg smell/taste.  Also, the faster you cool down the wort, the more oxygen will be absorbed by the wort, which will facilitate yeast growth. In general. the faster you cool it down, the better.

When I first started, I simply filled a sink or tub with ice and immersed the entire pot.  Essentially, this is what these guys did.  If you enjoy brewing, and end up doing it a lot, I suggest purchasing a 25 ft or 50 ft copper tubing wort chiller which looks like this, as these will chill the wort significantly faster than the ice bath and is a lot less messy.

Bring the temperature down to about 80-100℉ (You are going to want it to be at 70℉ after the water is added, so whatever it takes to accomplish that).

Don’t let the beer sit around too long once and make sure to only use sanitized equipment once it reaches 140℉, as bacteria can start to grow in here.  If a small enough amount of bacteria gets in here, it’s not a big deal, as the yeast will likely kill it off in the fermentation process.

Step 6: Primary Fermentation

Once cooled, pour vigorously into your fermentation bucket.  I would suggest a bucket and not a glass carboy as this may lead to vigorous fermentation can cause it to explode, sending glass all over the place. To help facilitate yeast growth, I’d suggest wisking the wort (though this is not necessary).  Add cold water to the bucket to bring the total volume of the wort to 5 gallons.  Adding this water should also bring the temperature of the wort down to 65℉-75℉.

Grab a sample of the wort and your hydrometer to measure the specific gravity (or density of the water, based on sugar content), as described in this video.  What they don’t tell you in these videos is that you can add a little more finishing (corn) sugar to the batch if you want to bring up the alcohol content.  I wouldn’t add too much,  because you don’t want to change the flavor of the beer.

If you are doing something that requires dry hopping (adding hops in the fermentation process), you can add the hops and they will just float on top.

Add your yeast starter, or if you skipped that step, just add the dry yeast.  Add the bucket top with airlock filled about half way with sanitizing solution, and just wait 7 days (or when the foam starts to disappear) to test your gravity again.  Once it is at about 1.010, you can transfer to secondary fermentation, or if you are skipping secondary, wait until it drops to about 1.004.  These numbers are approximate, so don’t worry if they aren’t exact.

Put this in a cool dark place for  7 days.  For an ale, you want to keep this around 70℉, for a lager you want to keep them around 50℉.  There’s a great article here about controlling the fermentation temperature.  Make sure to check occasionally that the airlock doesn’t get blocked up by foam and clean it out and replace it if it does.

Step 7: Secondary Fermentation (optional)

You can skip Secondary Fermentation if you just keep it in the Primary Fermentation stage for 14 days, but you have to keep an eye on it to bottle/keg it to avoid autolysis.

Secondary Fermentation allows you not to worry about autolysis (when dead yeast at the bottom starts to contribute yeast flavors to the beer).  It’s not necessary, but I suggest it.  I use a glass carboy for this step, but you can keep it in a bucket in this step as well.  To transfer it, I use a siphon with a hose.  This is because the yeast has become anaerobic and thus you should avoid adding much additional oxygen (don’t stir too much).

Let this batch sit for another 7 days.

Step 8: Filtering and Bottling/Kegging

After your batch has completed, we need to siphon the liquid into our bottling bucket or keg through a strainer.  Using your bottling bucket, pour the liquid from your bottling bucket into a bottle and cap.  Repeat until you are out of brew.

Let these bottles sit for 3-4 weeks to finish.

Here’s a video to help with this too

The hope that the Cable Company Regime might Die (Google Fiber, Aereo, and Senator McCain)

The hope that the Cable Company Regime might Die (Google Fiber, Aereo, and Senator McCain)

May 29

In some ways, law and politics is a game. Most of the time the big bullies push around everyone, but these days, things are changing.

I shared this with friends, but thought it merited sharing with the world. It’s funny because it’s true.

Google Fiber

Google Fiber not long ago announced that it is releasing another couple of zones. After a successful attempt with Kansas City (in both Kansas and Missouri), it is expanding. Lucky bastards in Austin.

For those who haven’t been paying attention to the Google Fiber thing, it’s interesting stuff. For $300, you get internet for 7 years at current cable provider speeds. Or, for the same overpriced amount you pay your cable provider for cable television and internet (~$120), you get the same cable package, plus internet that ranges from anywhere from 200 to 1,000 times faster (depending on your current internet speeds).

Yup, you read that right. 1,000 times faster.

It’s insane. It’s groundbreaking. And it’s going to happen, whether the cable providers want you to do it or not.

Aereo

From a cable spokesman, they “expect that you don’t want faster speeds because you haven’t asked for it.” Except in my area, where FIOS exists and people buy homes in the right areas just so they can get the Fiber Optic speeds, which are far below that of the Google Fiber project.

I would love to be able to buy HBO or TNT, but don’t want to buy ESPN. I support one product and not the other. But, since the cable companies and cable content providers are working in collusion and the cable companies are operating within state supported oligopolies, we are forced to take what they give us. What they give us is packages so that they can maximize their profits and advertisements.

Things like this give us options that are legal. Technically, the current regime is the one that is breaking the laws (spelled “Legal Monopoly”) with congressional support.

I would like to have local channels too, but don’t want to pay for the antenna or get up on a roof, even if that is able to happen. Plus, I don’t want to buy all of the equipment (slingbox, dvr, etc) to do this. I can, but I don’t want to. A fun new service called Aereo provides this service for you. They basically set up a an antenna, a dvr, and a slingbox, and give the control to you.

People and cable companies are up in arms over this. Everyone is screaming “Thief!” And when I say everyone, I mainly mean content providers and cable companies. Why? Because they have a nice little cash cow that they don’t want to see end. So what do they do? They take Aereo to court to sue the pants off of them. Turns out that Aereo was absolutely prepared for that. In a recent court case decision, they won the court case based on the fact that antenna, dvr, and slingbox are all legal for you and have been decided so in previous court cases. Plus one for the underdogs.

This is a valid service that they are providing. Just because you don’t like it doesn’t make it immoral or copyright infringement.

Senator McCain and the a-la-carte options

Even better yet, Senator John McCain, a man that I would not say that I align with politically, has a fabulous idea that he sent to the New York Times.  Basically, a-la-carte pricing has been requested for about 20 years by the government.  The FCC doesn’t want to step in and get involved in that, because that would be government putting limitations on businesses, which would be a political crap-storm.  However, he is willing to cut off the subsidies that they are getting from the government when they don’t do this.  BAMN!  Thank you Mr. McCain!  It’s about time.

The cable companies are putting pressure on companies that might take their business (Google, Microsoft), but they can only do so much. With the updates to the Home Theater PCs (by Dell, Boxee, Plex, XBMC, and even the new XBoxOne, for better or worse), it’s possible to connect your home in ways that were unheard of.  The only problem is that the content is still coming.  It’ll get there soon enough though.

Hope

With all of these different forces building, it might just be possible to losen the grip of some of the worst-liked companies in the US today.  Here’s for hoping, right?

Stupidest Google Groups Message I Have Ever Found

Stupidest Google Groups Message I Have Ever Found

May 24

I understand that google groups has upped the number of permissions that people can tweak. That way, you have separate permissions to join, post, reply, etc. If you want to be a nazi in your group, they give you the power. However, I came across the most ludicrous message I have seen from any google application:

“You do not have permission to leave this forum.”

And just so that folks don’t think I’m just making it up, I took a screenshot.

Screen Shot 2013-05-24 at 2.29.44 PM

Now, I know that Google Groups isn’t the most feature rich forum software out there, nor is it the most feature rich newsgroup software. Unfortunately, I have now relegated this to “The place where the retard Google devs get to play.” This is because, whomever thought that this was an appropriate message or rule to make, falls into that category.

(PS – Sorry if I insulted any special needs kids. Just know that you can make fun of some of the Google developers now.)

Simple Groovy-isms

Simple Groovy-isms

May 17

You learn pretty quick when switching over from Java to Groovy. Problem is that it is fairly backwards compatible, so if you aren’t doing something in the easiest way possible, it may be hard to know. For the basics, I just want to state them so that everybody is at least covering the basics.

Scoping

By default, classes are public in groovy. Don’t add the public keyword. Similarly, member variables are private. The accessors and mutators are generated (as you’ll see in the next section).

Accessors and Mutators

Accessors should be adjusted from

dbCollection.getMyVar()

To the following

dbCollection.myVar

Similarly, the mutator

dbCollection.setMyVar(10)

should be used as follows

dbCollection.myVar = 10

It looks like you are accessing the private method, but it’s not. It’s just shorthand for calling the “get” function. This is important because even if there is no member variable – such as x.getCount(), this should still be called using x.count. That’s one of the fun shortcuts in Groovy.

GStrings vs Strings

You should know the difference. It’s pretty important. For info about these, click here. It covers it in depth pretty well. Basically, just know that single quotes and double quotes are very different. And if you use 3 double quotes or 3 single quotes to start a string, you are doing a multi-line string.

Using this, your strings should be adjusted from the following Java-like syntax
dbCollection.insert("abc" + var1 + "def" + var2.prop)

To the following
dbCollection.insert("abc $var1 def ${var2.prop}") (Gstring parses faster using the formatter and string buffers)

Print statements

Although I would suggest that you use something like log4j/slf4j/etc rather than printing directly to the console, print statements get easier:

System.out.println("something")

Should be changed to

println 'something'

Collections

There are so many goodies added to the collections GDK that it’s very hard to cover it all. But syntax-wise, there are only a minor couple of changes to make:

For maps, accessing and

Map m = new HashMap()
System.out.println(m.get('abc'))
m.put('abc', 2)

should be

Map m = [:]
println(m['abc'])
m['abc'] = 2

Also, the following also works to the same effect

Map m = [:]
println(m.abc)
m.abc = 2

For lists, this

List arr = new ArrayList()
System.out.println(arr.getAt(2))


Array arr = []
println(arr[2])

For statements

Basically, don’t use them anymore (there are a couple of valid cases, but they are mostly not necessary within groovy.  The following for statement

for( i = 0; i < 20; i++ ) { funcCall(i) }

can be rewritten as

(0..<20).each { funcCall(it) }

This uses the range object within groovy.  For more details on the Range Objects in groovy, click here. Also, it then uses the each function on the range object, passing it one parameter, a Groovy Closure. Closure's are one of the most powerful things in Groovy. It allows you to design very functionally (rather than in a totally object-oriented way). For more information on these, please visit Groovy's Closure page.

Nearly The Only One Even Thinking of Buying a Chrome Pixel

Nearly The Only One Even Thinking of Buying a Chrome Pixel

Feb 24

Yup. You read that right. I think I’m nearly the only one on the planet even thinking that buying a Chrome Pixel might be worth something.

After the rediculously true reviews that have been coming out – some reasonable, and some just brutal.  The short and long of it is that there is no hard drive.  What are you supposed to do with that?  OK, they are pushing you to the cloud, we get it.  And actually, I mostly am doing that anyways.  I actually am able to do a bunch of my work on an iPad at this point.  All I need is a shell terminal to an AWS Server, really.  Unless my work needs me to do something fairly intensive.  But I could have another laptop for that, right?

It’s a REALLY nice screen though.  I can get over the fact that there are no function keys – only the Chromebook specific keys. The Google development team has shown us how to run Mint Linux on it too, so you can have something that is more than a web browser.  Just don’t install too many programs.  Of course… then your fancy multi-touchpad doesn’t work.  Neither does your touchscreen (which, let’s be honest, you weren’t going to use anyways).  Also, Mint isn’t exactly set up to handle high resolution vector graphics like the comparable Retina MacBook.

OK, it’s a stupid idea.  I told you I was thinking about it, not that I was going to do it.

My New Favorite Toys

My New Favorite Toys

Feb 15

OK, I’m going to admit it.  I tend to get really excited about Configuration Management (CM) type work and I have no idea why.  This is one of those.

Machine Images/Virtual Machines

Ok, these have been around.  If you don’t know what a machine image is, then stop and go download Oracle’s VirtualBox, because it is something that everyone should know.  These were revolutionary when they first were introduced.   So much so that most Operating Systems support some form of images (disk or machine) right out of the box.  Especially because a number of companies, including VMWare and Parallels, found out that they could manage your hardware better than the Operating System (which was originally supposed to do just that, but has really turned into something much more complex and more like a user interface). So, it turned out that if you used machine images, you could have a snapshot to a point in time. Sure, it still required some configuration after getting it going, but after that, it was cake. IT departments (and Dell/Norton, with their Ghost Image partition) were loving it. It really cut the mind-numbing monotony of setting up new boxes.

Puppet and Chef

Essentially, Puppet and Chef do the same thing.  Both start on the assumption that you have a base image installed on your box. Both represent a language that gives you the ability to install the software, users, and whatever else is necessary on a box to have it ready for tasking.  Both have claimed to support all major OS options.  This way, you could install the same users on the Windows boxes and Unix boxes in one script!  Of course the multiplatform argument is crap, but it still is a great option to finish what Machine Images started.

Take passwords for example.  Each OS handles this so completely differently that you would have to create a different module for the password for each OS.  Too much hassle.  Most companies are going to pick an OS and stick with it.  Heck, most are going to pick the same hardware too. This is the suggested use for almost all companies anyways.  Google, Yahoo, Amazon, etc. all use proprietary hardware.  But it’s THE SAME proprietary hardware.  Every machine has the same specifications.  (If you want, check out the Google server machines or the data center).  And I’m guessing most of them aren’t Windows boxes.  Just sayin’.

So, you create a new machine configuration for each type of machine.  One for your Web servers, one for the database servers, etc. Makes scripting all boxes that you might want to make really easy. Plus, in a cloud environment, like Amazon EC2 or privately held HDFS clusters, this makes setting up servers a breeze.

The difference between Puppet and Chef is their target audience.  Although they are technically competing products, both companies have pretty much stated that their real competition is the rats net of batch/shell scripts that you’ve probably written, or even better yet the documented instructions like the following.  We’ve all written these before.  And they even sometimes work.  Sometimes.

Vagrant

Another fun toy. So now, assuming you start using the Puppet/Chef to start requisitioning your servers, everything is great. Every server that gets started is always the same. Starts from the same image. Now you know that every server will run the same. Huzzah! But as every web developer knows, we don’t test enough for IE. Why? Because as a developer, I f’ing hate it. Because I don’t use it, I probably miss bugs.  Same applies to servers.  I’m missing bugs because I work in Windows or OS X, but deploy to a totally different environment.

Vagrant is a fun new tool that takes that really nice puppet script and image that you’d made, load it into a virtual machine, and run it in the background.  That way, you have the exact same environment that the server has, but on your local machine.  So, if you need to, you can ssh into it.  You can update your puppet scripts and push changes to it.  It also does port forwarding from your machine to your virtual machine, so that any exposed REST service or port is fully accessible via a web browser.  (If you want to play with it, the best install guide I found is here).

Now, you can avoid the annoying statement from your coworkers that is “Well… it works on my machine.”  Because I don’t care if it works on your machine.  Now, I only care that it works on the production environment.  You have it locally, so make sure to test it there.

Boxen

My new toys just got better.  Your IT department can now set up your computer for your project within minutes by using a new product called Boxen.  This is also based on Puppet and brought to you by the GitHub folks (who also brought you Hubot).  This software was originally designed to install project specific files and programs on OS X, but since Puppet is very much a OS independent tool, I’m guessing it will work on Linux (Good luck Windows guys.  Although Puppet might work, I doubt the tool will, but only time will tell.)

Overview

So, the tools are changing to help us stand up and deploy 1 to 1,000 servers with ease. Developers can run the exact same environment is working there. Now, we should wait and hope for Internet Explorer to give up on their web engine, much like Opera did (some say for performance reasons) and we might eventually get to a uniform presentation platform as well.  Wouldn’t that be nice?

Learning New Technologies

Learning New Technologies

Feb 13

For some people, it’s like pulling teeth.  I’ve spent all of this time learning Java (which most people still can’t use effectively) and now you want me to start over with something new?  Ludicrous!

One of my coworkers recently posted a great comment, which came from Zemanta:

I agree, I can’t keep up, I just finished learning backbone.js and now I’ve found out on HN that it’s old news, and I should use ember.js, cross that, it has opinions, I should use Meteor, no, AngularJS, no, Tower.js (on node.js), and for html templates I need handlebars, no mustache, wait, DoT.js is better, hang on, why do I need an HTML parser inside the browser? isn’t that what the browser for? so no HTML templates? ok, DOM snippets, fine, Web Components you say? W3C are in the game too? you mean write REGULAR JavaScript like the Google guys? yuck, oh, I just should write it with CofeeScript and it will look ok, not Coffee? Coco? LiveScript? DART? GWT? ok, let me just go back to Ruby on Rails, oh it doesn’t scale? Grails? Groovy? Roo? too “Springy?” ok, what about node.js? doesn’t scale either?? but I can write client side, server side and mongodb side code in the same language? (but does it have to be JavaScript?) ok, what about PHP, you say it’s not really thread safe? they lie?? ok, let me go back to server coding, it’s still Java right? no? Lisp? oh it’s called Clojure? well, it has a Bridge / protocol buffers / thrift implementation so we can be language agnostic, so we can support our Haskell developers. Or just go with Scala/Lift/Play it’s the BEST framework (Foresquare use it, so it has to be good). of course we won’t do SOAP and will use only JSON RESTful services cause it’s only for banks and Walmart, and god forbid to use a SQL database it will never scale
I’ve had it, I’m going to outsource this project… they will probably use a wordpress template and copy paste jQuery to get me the same exact result without the headache and in half quarter the price.

This is hilarious, and very true.  These are new technologies all of them.  You can’t keep up with everything.  But if you haven’t spent a week programming with one of them, my suggestion is to not shoot it down so fast.  These are all tools.  And although, as a craftsman, a builder may be able to do many things with a Power Miter Saw.  Heck, it might be your go-to tool for most things that you do.  Just know that it’s not the tool for every job.  And fighting anyone who offers you a reciprocating saw because you don’t want to learn how to use it is silly.  Same applies to programming.  Get the tool, whether that is Ruby, Clojure, NoSQL database libraries, or just a simple new (to you) JavaScript Library like Backbone (here, have a tutorial).  Play with it for a while.  Read about it’s suggested use.  You’ll find out really quickly that sometimes it’s really useful for some jobs, and not for others.

For example, here’s a great article about Functional Programming.  Does it apply to someone writing a single server solution?  Nope.  So now you know that this doesn’t apply, and that it might not be the best tool for you.  But if you are working on something that will horizontally scale, this is the stuff for you.  See what I mean?  Different tools for different people.  Once you get the hang of trying them out, it gets easier to evaluate others.  Which makes you a better programmer.

Accessing Java Resources (a.k.a. getResource vs getSystemResource)

Accessing Java Resources (a.k.a. getResource vs getSystemResource)

Jan 04

This isn’t a tough article, but one that I always forget and have to look up. This is useful for everyone who has to touch Java for the first time or experienced users who just forget (like me).

Adding a resource, especially when using a build tool Maven, is quite easy. You just include it in the jar (which in maven, is by putting it in ${projectdir}/src/main/resources). Getting it back out is a little trickier, but not too bad.

The easiest way to access this is to use the getResource instead of getSystemResource, which are on the Java Class Loader, to use a resource specific to a given classloader instead of the system. For example, try any of the following:

1
2
3
4
URL resource = getClass().getClassLoader().getResource("R.txt");
URL resource = Foo.class.getClassLoader().getResource("R.txt");
URL resource = getClass().getResource("/R.txt");
URL resource = Foo.class.getResource("/R.txt");

Note the leading slash when calling Class.getResource instead of ClassLoader.getResource; Class.getResource is relative to the package containing the class unless you have a leading slash, whereas ClassLoader.getResource is always absolute.

Also, as a side-note, if you are trying to access resources from a dependency, don’t. You are doing it wrong. This is possible, but bad design and hard to implement.