Tuesday, 23 July 2019

Is Rails broken?

I am increasing worried that Ruby on Rails is not a stable environment. I was trying to update my project, and hit error after error in the infrastructure.

Warbler does not work with JRuby 9.2.7

See here:

Using an earlier version resolves it. Is this a Warbler issue or JRuby? Who knows, but it starts to shake my confidence.

It would help if Warbler gave some clue it was doing something. It takes around 30 minutes for me, during which it reports that is is deleting the old version, and later that it is creating the new one. Most of that time.... Nothing. Has it crashed? Who knows.

Cannot create new projects with Rails: 5.2.3

I was trying to do this to investigate other issue, and found I could not even create a new project! This is basic!

I started a thread on Stack Overflow, without much response.

I tried three different versions of Java, two versions of Windows, two versions of JRuby:

Java: Zulu 11 (64 bit), Zulu 8 (32 bit), 1.8.0 (Win7)
JRuby: 9.2.7, 9.1.17

Turns out I can use Rails 5.2.2. It produces a Rails 5.2.3 project, but does work. But seriously, why would I choose to use something that is obviously broken?

Rake version mismatching

How often do I see this error?

Gem::LoadError: You have already activated rake 12.3.0, but your Gemfile requires rake 12.3.2

I have no reference to Rake in Gemfile, and I can delete Gemfile.lock, but still there is a mismatch between versions when I do bundle. This is exactly what Bundler should be preventing. The solution is to uninstall rake, then install the version the Gemfile requires, 12.3.2 in this case. Why does Bundler not do that?!?

Tomcat will not run my project.

I just see this error on the screen (and no errors in any of the log!):

Trying to register Bundler::GemfileError for status code 4 but Bundler::GemfileError is already registered

This is with both JRuby: 9.2.7 and 9.1.17, and Rails 5.2.3. I tried Bundler 2.0.2, 2.0.1 and 1.16.6, as I suspected it was the culprit, but none worked.

Google cannot find ANY pages with that exact error... It could be because I have Rails 5.2.2 installed, but much of the other rails gems are 5.2.3

My production server is running Tomcat 9.0.14, and 32 bit Java jre 1.8.0 191, so I started from scratch, with Tomcat and Java as per the server, and the last .war that works on the sever, and got that working on my PC.

Then I copied gemfile and gemfil.lock from the working version to the new, and ran bundler successfully, but warbler then said:

Gem::LoadError: You have already activated rake 12.3.0, but your Gemfile requires rake 12.3.2.

Why had that reverted to 12.3.0? Who knows. I had been messing around with Rails versions, so could have done it by accident.

I still do not know the underlying reason for the error, but at least it is running now.

Is Ruby on Rails Broken?

I have to wonder. It feels less stable at version 5 than it did at version 2 or 3 when I adopted it 10 years ago. I would have hoped it was getting more stable as it gets more mature, not less.

I want a framework I have confidence in, and Rails is not that any more.

Monday, 17 June 2019

You must use Bundler 2 or greater with this lockfile.

I have been getting this error recently when doing some things, but not others... These worked:

rails c

rails test

rails test:models

These failed:
jruby -S rake test:models

jruby -S rails test:models

jruby test/models/db_section_test.rb

The error message suggests it is using an earlier version of Bundler, so I spent ages hunting down any rogue version, deleting old versions of JRuby, searching folders and gemfiles. Version 2.0.1 was definitely the only one, so how come it was complaining?

I was also suspicious of JRuby.

Eventually I found a Github discussion for bundler, with the solution buried pretty deep. This seemed to fix it.

gem update --system

bundle (not sure if this was needed)

gem install bundler

Once gem was updated, a new bundler version was available, 2.0.2, and all seemed well at first, but I layter hit upon this:

Gem::GemNotFoundException: can't find gem bundler (>= 0.a) with executable bundle

This seems to occur because JRuby 9.2.7 comes with a slightly older version of Gem, one that cannot run Bundler 2.0.2 (is there really so big a difference between 2.0.1 and 2.0.2?).

I never got this to work, and the only solution was to start from scratch, re-installing JRuby, and install Bundler version 1.16.6.

Updated gem is a bad idea too, as it them tries to run ruby.exe, rather than jruby.exe.

I guess you need to use a modified version of gem for JRuby, which currently is still on 2.0.1 or equivalent, and that means if you are using JRuby, stick with Bundler 1.16.6 for now.

Wednesday, 29 May 2019

Functional testing with Rails 5

I have not blogged here for a couple of years, mostly because my blogging was part of the learning process, and I got to a point where I knew enough to get by. I upgraded to Rails 5 a little while ago, somewhat late because I use JRuby, and I waited for them to be compatible. I am not adding two new models/controllers to my project, and found out about functional testing in Rails 5.

There is none.

It has been replaced by integration testing.

Okay, I can see the point. You want to test if a request gives the right response. If the user has to log in first, you do the request first, then do the one you want to test. However...

Updating tests

I have over 800 functional tests in my project. If I do a full upgrade to Rails 5, then I have a huge amount of work modifying each and every test.

And I do mean every test, as the way we make requests has changed fundamentally, so:

get :new

... has become:

get root_path

The parameters are different too, so a simple find/replace is not going to work here.

At the moment, that is not necessary, but functional tests are to be deprecated, so it is either update all 800 or so tests or add another gem to the project.

No assigns

Integration testing is "black box", it gives no way to look inside to see what variables are getting set. This seems like a really bad idea in practice.

How can it possibly be a good thing to stop checking something? Because that is what I will have to do. A fair proportion of those 800 tests check the value of a variable or three. If they stop doing that, then I cannot be as confident that passing the test means the code is actually okay.

Another big problem is that I use assigns as a way to see what is going on when a test fails. With integration testing, I will know it fails, but have no idea why. Again, it feels like Rails is deliberately withholding useful information, just because it is philosophically better to do it this way.

Backwards compatibility

If only! Changes like this make me regret choosing Rails. I doubt I would choose it again, to be honest.