It Works On My Machine

      No Comments on It Works On My Machine

As a developer the worst 5 words that can ever come from your mouth is “It Works On My Machine”. Your code works, passes all its tests, but when the client runs it the code fails in some way and you can’t replicate the problem.

No need to wait for a conclusion before the story. Its your fault. Get used to it. It is unlikely that you have discovered a bug in Java or any language you are using. No need to waste time googling “Bugs in Java”. Look at your code, its your fault.

I had such an experience and thanks to the eagle eyes of one of my students the error was found quickly. Here is what happened.

I asked my students to run sample code that will send and receive a plain text email using the Jodd Email library. This program was initially written in 2015 but had not been updated since then. When I reviewed it for use this semester, I had to deal with changes to the Jodd API. Nothing serious, just annoying. With the changes made I ran the code. It only uses a unit test to send and receive. Success, it worked, and so I pushed the update to the repository and told my students about it.

It did not take long to get a report about the unit test failing. How could this be? I ran the code again and it worked fine for me “on my machine”. This is where a student spotted the problem. In the unit test I had a line that read:

mailBeanSend.getToField().add(“cst.receive@gmail.com");

I had used a literal string to define the To: field. The problem was that this address was going to be different for every student as they were told to use their Gmail accounts. The repo had my Gmail credentials removed. By neglecting this line I had a program that could only pass its test if it’s To: field read “cst.receive@gmail.com” which is what I used. Therefore, it always worked on my machine.

The fix was easy. The new line reads:

mailBeanSend.getToField().add(receiveConfigBean.getUserEmailAddress());

Case closed. Another case of “It works on my machine” resolved.

How to submit a pull request to an Eclipse project – Update

This is part 2 of my adventure in adding a new example project to the Examples for Jakarta EE project, part of the Eclipse EE4J project https://projects.eclipse.org/projects/ee4j. The Examples web page is at https://projects.eclipse.org/projects/ee4j.jakartaee-examples. The GitHub repository for the project I am making my pull request for is located at https://github.com/eclipse-ee4j/jakartaee-examples. I am assuming that you already know which project you wish to contribute to.

Step 1: Create a GitHub account

The Eclipse EE4J projects are all on GitHub. The process to contribute to a project requires that your identity, specifically your email address, on GitHub must be the same email address you will use to join Eclipse. If you do not already have a GitHub account create one with the email you will use when you join Eclipse. If you already have an account, make sure that you use that account’s email address to join Eclipse.

Step 2: Install the GitHub Eclipse ECA Validator

This is a GitHub app from the Eclipse Foundation that analyzes a pull request to determine if it follows what is expected. It would have saved me some time if I recognized its importance earlier on in my adventure. Some of the steps below came out of running this and discovering what was wrong with my request.

Do not look for a button to run it. It executes when you make a pull request. When you make the request on GitHub you are given two choices, Pull Request and Draft Pull Request. Do a Draft Pull Request so that you can see if you comply before you make the formal request that is sent off for approval to the project maintainers.

You can find the app at https://github.com/apps/eclipse-eca-validation

Step 2: Join Eclipse

Go to https://www.eclipse.org/ and log in. But wait, you do not have an account to log in with. Not to worry, Eclipse hid this link on their Log In popup. Look for the choice to ‘Create new account’.

I will not go thru the steps to become a member as they are straightforward. Along the way you will be asked about signing an Eclipse Contributor Agreement. You must complete this agreement to be allowed to contribute code to any project. If something goes wrong that you do not notice, then the very nice people associated with the project you wish to contribute to will provide you with guidance to resolve any issues.

Step 3: Join Mailing Lists

Every project has a mailing list that you will find on a project’s web page. There is a general web page with all the Eclipse mailing lists but this is not the friendliest place to find a list unless you already know its name.  Since I am in interested Jakarta EE, also know as Eclipse-EE4J, I went to https://projects.eclipse.org/projects/ee4j. On this page select Contact Us. I assumed such a choice would bring me to an email address I can use to get more info. In the Eclipse world contact is by mailing list. It works extremely well and as I had difficulties doing my first pull request I posted to the list and received suggestions quickly.

Bonus Round: How to Join a Project

You cannot, at least as far as I can tell. Once you have signed the Eclipse Contributor Agreement you may submit a pull request to any project. The members of that project may then choose to invite you in as a member/committer/maintainer. Remember, you can contribute to any project even if you are not in the inner circle.

Step 4: Fork the GitHub project you wish to contribute to

I am not a Git guru. A little research revealed that there are two ways create a pull request. One is to clone a project and create a branch with the changes and additions you wish to submit. The issue with this approach is that you will need write privileges to the project to submit your branch. You do not.

The second approach is the one you will use, and it involves forking. This means that GitHub will copy the Eclipse project to your GitHub repository. There is a fork button on the jakartaee-examples page to do just that. In your own repository you have free reign to do whatever you want. Clone this forked project to your computer and make your changes and additions.

Step 5: Verify that you can compile and, if present, run any tests on the project.

You can read how I did this for the examples project at https://www.omnijava.com/2020/04/25/how-to-work-with-the-eclipse-ee4j-jakarta-ee-examples/. Take note of the Java version for the project you are working on. The JakartaEE projects all expect Java 1.8. I used Java 11 with a compliant application server in my courses this past semester and Jakarta EE 8 libraries all worked running in Java 11. I verified that my example ran as expected with Java 1.8.

Step 6: Analyze how the project you are submitting to is constructed

I cannot speak on any project other than the jakartaee-examples, but I assume there are similarities between all the projects. They are all Maven based and are organized into modules. In the case of the examples there are 113 individual projects spread amongst the modules. My project is destined for the Servlets Examples module where there are already six projects. My contribution is going to be the seventh. You will have to determine where your project’s folder will need to go in the project.

Step 7: Integrate your example into the style of coding already in place

I had already prepared my new example program that I wished to submit as a standalone project. I was fortunate to have a member of the examples project look it over. He told me that while the content is appropriate it did not comply with the standard format of all the projects.

Here is what was pointed out to me or what I learned.

a) Place your project folder in the appropriate place in the project’s hierarchy. The jakartaee-examples project has three levels. I placed my folder in the appropriate location with other projects associated with the second level module ‘servlet’. Take note of how project folders are named and follow the pattern.

b) Review your pom file and the pom files of projects in your level and above. Your pom file must depend on the pom file of the module you are in as well as any other pom files higher up in the project. You should not be adding any dependencies.

Review your pom.xml tag ‘name’. Give your project a name that matches the style of other projects.

In a Maven module system, the pom file above you will list your project as a module so you will have to update it. The module name is the folder name your project is in. The folder name and pom ‘name’ tag are not necessarily the same.

c) A licence header is required at the beginning of every source file. Here is its first line:

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.

The subsequent lines are legalize asserting that the code is being supplied “as is” and absolving the author, you, of any or all liabilities.

d) The package names I used did not match the format of other projects. For example, I had:

com.omniprof.thelearningservlet
To make it compliant I changed it to:
jakartaee.examples.servlet.thelearningservlet

e) All the example projects do something, effectively they are small web apps, rather than being a library. They demonstrate how a library, such as Servlets work. Therefore, they require unit tests. My demo is quite simple and using as a template an existing test I was able to easily create a test class. There needs to be a test for every action. My code demonstrates calling doGet and doPost in a servlet. Initially I only wrote a test for doGet. It was pointed out to me that every path in my program needed a test, so my unit test class now has two tests.

f) Only Jakarta libraries can be used in the demo code. I am fond of slf4j and log4j in my server-side coding. As they are external libraries, I dropped them in favour of java.util.logging. For test code external libraries can and likely need to be used such as Arquillian. It is the example of a Jakarta EE library that must not rely on an external library or framework.

g) The commit message must have a Signed-off-by footer. This was something I initially neglected. A footer is the last line every commit and must read, as in my case:

Signed-off-by:Ken Fogel omniprof@gmail.com

Fortunately, I found that I could get my IDE to add this automatically.

h) Review all the README.md files. No one told me about this, but I spotted it after I submitted a pull request. I had not noticed that the README.md for the servlets module had an list of all the projects in the module. I had also neglected to include a README.md in my project.

i) Make sure that your local Git repository is signed with the same name and email address as the Signed-off-by footer. If you go into the .git folder you will find a file named ‘config’. Make sure a section like the following appears in your file at the end:

[user]
        name = Ken Fogel
        email = omniprof@gmail.com

j) Create JavaDocs. By creating JavaDocs you can find errors or omissions in your comments. For example, I had @return tags without a comment explaining what was being returned. In a JavaDoc block I had a line that read CRUD -> R and it turns out that ‘->’ is an issue. I did receive warnings for my @throws where the exception class name is shown. I did not comment how the exception might occur because these were in methods I was overriding so the reason could be found in the JavaDocs of the overrode method [added 2020-05-04]

Step 8: Compile the entire project and run all its tests

Your code my be fine as a standalone but it may not run or test as part of the entire project. This is likely not a worry if the project is a single application but as the examples are multiple projects it must be verified. It took 31 minutes to run all the tests for the 114 examples.

Step 9:  Commit and Push

Commit your code to your local repo. Do not forget the Signed-off-by footer as described earlier. With that completed successfully you can push the project to your fork in your GitHub repo.

Step 10: Create a Pull Request

This is easy to do as GitHub recognizes that the reason you did a fork is likely to make a Pull Request. As mentioned in Step 2, the ECA Validator will inform you if your request is valid. Therefore, do a Draft Pull Request first and if it reports all is well then do the Pull Request.

Step 11: Wait

The project maintainers are all volunteers. They have jobs that keep them quite busy. Sometimes you may get lucky and get feedback quickly. Other times it could be days or longer before you hear anything. Be patient.

There you have it. As of this writing I have finally submitted a Pull Request that I think met all the technical requirements but has not been accepted yet. The purpose of this blog is to review the tasks necessary to make a successful pull request. What is in the request may not be what is required or needed so pay close attention to the feedback you may receive.