Hazelcast recipe

Hello guys. I’m new to this forum and I don’t really know if this is a question for you all, but I hope that someone here will send me to the right track.

First the setup: VM on a hyper-v host with Centos 6.6 and chef-client installed, VM bootstrapped to the chef-server (centos)

At work we decided to have a (semi)automated way to deploy hazelcast on the local envs and for that we’ll be using Chef. I tried to use simple-hazelcast recipe from https://supermarket.chef.io/cookbooks/simple-hazelcast and as I lack the experience on working with these recipes, although a simple recipe, I didn’t quite understand how it works.

My run list is includes and installs jdk and simple_hazelcast::default which runs one by one: user, install, configure and service_runit. All goes well, but in the end:

 [root@hazelcast_poc ~]# tail -3 /var/log/hazelcast/current
 2016-04-16_13:51:56.55516 Error: Could not find or load main class com.hazelcast.core.server.StartServer
 2016-04-16_13:51:57.56414 JAVA_HOME environment variable not available.
 2016-04-16_13:51:57.77994 Error: Could not find or load main class com.hazelcast.core.server.StartServer

JAVA_HOME is set to /usr/java/latest as seen below:

  [root@hazelcast_poc ~]# echo $JAVA_HOME
  /usr/java/latest

As I don’t have too much experience with Java, I do not understand what that means:

  Error: Could not find or load main class com.hazelcast.core.server.StartServer

Any help would be highly appreciated.

Thank you.

Best regards

I think your problem is likely that node['hazelcast']['java_home'] defaults to nil. Set that to the correct value and you should be OK, or at least it sounds like you’ll be one step farther. Keep in mind, just because $JAVA_HOME is set for the root user doesn’t mean it’s set for the user this recipe creates.

If you’re wondering how to set node['hazelcast']['java_home'], there are a few ways. The easiest is probably to use a Chef role, which would look like this:

name 'hazelcast'
description 'Role - sets up Hazelcast'
default_attributes({
  'hazelcast' => {
    'java_home' => '/usr/java/latest'
  }
})
run_list 'recipe[simple_hazelcast::default]'

Remove the simple_hazelcast::default recipe from your run list, then add this role, re-run Chef Client and see what happens. You could also just add your Java recipe to the role’s run list and have only the role in your node’s run list.

If setting that path doesn’t help, your next problem might be that node['hazelcast']['class_path'] also defaults to nil.

1 Like

I’ve solved the the first problem by modifying the attribute

default['hazelcast']['java_home'] = '/usr/java/latest' 

in the recipe.

The second problem,

 "Error: Could not find or load main class com.hazelcast.core.server.StartServer" 

was solved by exporting the jar to classpath in a script in /etc/profile.d/, something like:

     [root@hazelcast-poc ~]# cat /etc/profile.d/jav.sh
     #!/bin/bash
     JAVA_HOME=/usr/java/default
     PATH=$JAVA_HOME/bin:$PATH
     export PATH JAVA_HOME
     export CLASSPATH="/opt/hazelcast/hazelcast-all-3.6.2.jar"

The real problem is now that after installing latest hazelcast (3.6.2) is seems like it doesn’t provides (creates) any hazelcast.xml configuration file.
Gabriel

That’s an easy enough problem to fix, and a learning opportunity for you :smile:

Create a blank cookbook with these few lines in the default recipe:

include_recipe 'simple_hazelcast::default'

template '/path/to/hazelcast_config_file' do # this is where you want your app config file to live on the server
  source 'hazelcast.xml.erb'
  owner  'someuser'
  group  'somegroup'
  mode   '0644'
  variables(
    :foo => 'bar'
  )
  notifies :reload, 'service[whatever]'
  action :create
end

Now, from this empty cookbook’s main directory, do:
mkdir -p templates/default
Then create a file under templates/default called hazelcast.xml.erb. Within it, copy-paste a bog standard Hazelcast XML config file. I don’t know what they look like, and I understand they’re XML, but just bear with me for this non-XML example to illustrate the concepts of using Chef templates. Let’s assume your bog-standard config file looks like this:

port=80
hazelcast_root=/var/lib/hazelcast
etc.

You’d probably want to be able to configure all the lines with Chef attributes, so what you’ll do is start assigning variable names to all the values within the config file so it looks like this in the end:

port=<%= @port %>
hazelcast_root=<%= @hazelcast_root %>

And back to your recipe, you would declare those variables in your template stanza and make them look up their values from your cookbook’s attributes:

template '/path/to/hazelcast_config_file' do # this is where you want your app config file to live on the server
  source 'hazelcast.xml.erb'
  owner  'someuser'
  group  'somegroup'
  mode   '0644'
  variables(
    :port => node['hazelcast']['port'],
    :hazelcast_root => node['hazelcast']['hazelcast_root'],
  )
  notifies :reload, 'service[whatever]'
  action :create
end

Finally, in your cookbook’s attributes/default.rb, you can set defaults for those values:

default['hazelcast']['port'] = 80
default['hazelcast']['hazelcast_root'] = '/var/lib/hazelcast'

More info about templates here: https://docs.chef.io/resource_template.html

If you don’t feel like doing all that, you can simply write a Hazelcast config file that matches how you’re trying to set up the application, store it inside the cookbook’s files/default directory and use a cookbook_file resource to write it to the desired path on your node.

I hope this helps!

1 Like

Yep.

I really appreciate your help.
It’s remarkable simple, yet I did not think of that because I was thinking that maybe this hazelcast version is free and it doesn’t come with too many configurable things. I’m an idiot.

Thank you very much.

Best regards,
Gabriel