Thursday, May 14, 2015

Issue with ins_ctx.mk during Oracle 11g install on CentOS 7

Installing Oracle 11g Enterprise on CentOS 7 didn't go quite as smoothly as planned.  However, by combining knowledge across several articles I was finally able to make it work.

During the install I received an error that wasn't mentioned in the Oracle install procedures or the article I used to guide the install at "Link 1" below.  The error was when the installer was trying to call a target in "ins_ctx.mk".  The message was:

INFO: /lib64/libstdc++.so.5: undefined reference to `memcpy@GLIBC_2.14'"

The solution essentially involved installing glibc-static and making the necessary updates to the ins_ctx.mk file.  See "Link 3" below for details on how to resolve the error.

To install Oracle 11g Enterprise, first follow the steps in the post at "Link 1" below, but you will likely encounter the error described above during the "Link Binaries" phase of the install.  If you do, then follow the steps in "Link 3" to resolve the issue with "ins_ctx.mk".

Link 1: http://dbaora.com/install-oracle-11g-release-2-11-2-on-centos-linux-7/

Link 2: http://oracle-base.com/articles/11g/oracle-db-11gr2-installation-on-oracle-linux-7.php

Link 3: https://web.archive.org/web/20140927033722/http://www.habitualcoder.com/?p=248

Tuesday, May 12, 2015

Oracle Enterprise Manager 11g Installation Error - Listener is not up or database service is not registered with it.

While attempting to install Oracle Enterprise Manager for Oracle 11g during the last phase of the Oracle 11g installer, it encountered the following error.


After checking to ensure the listener was up and doing a tnsping to the instance via the cmd window, I was at a loss so proceeded to Google to try to find the answer.  After some digging, it seemed to be a fairly common problem.  However, none of the solutions worked for me.  At least none of them individually.  After piecing together several solutions that others posted I finally was able to get the installation to succeed.  Hopefully this helps you if you are stuck in a similar situation.

Note that this installation is on a machine without a static ip or domain.

If you haven't done so already, make sure to add the <ORACLE_HOME>\bin directory to your path so that you can run the Oracle utilities without having to be within the <ORACLE_HOME>\bin directory itself.

Let's get started!

First, install the Microsoft Loopback Adapter.  This will allow you to specify a dummy host/domain on the loopback ip.  See the following Microsoft TechNet post for details:
https://social.technet.microsoft.com/Forums/windows/en-US/259c7ef2-3770-4212-8fca-c58936979851/how-to-install-microsoft-loopback-adapter

Once you have the loopback adapter created and have updated your hosts file, stop the Oracle listener via the command line using the command "LSNRCTL.EXE stop".  Use the "Net Configuration Assistant" to remove the listener and add a new one with all the default values and the same name.

Next, you will need to update your listener.ora and tnsnames.ora files to set the host as the dummy host/domain you specified in the hosts file.

The listener.ora file located at <ORACLE_HOME>\network\admin will contain something similar to the following:

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = <YOUR HOSTNAME>)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

The tnsnames.ora file located at <ORACLE_HOME>\network\admin will contain something similar to the following:

<DB_SID> =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = <YOUR HOSTNAME>)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = <GLOBAL DB NAME>)
    )

  )

Now you will need to start the listener back up again using the command "LSNRCTL.EXE start".

Ensure the listener is up by using "tnsping <db sid>".

Next run the command "emca -config dbcontrol db -repos recreate" as Administrator and follow the configuration prompts displayed.  If it completes successfully it will also list the URL you need to go to in order to view the Enterprise Manager page.





Thursday, March 12, 2015

Parsing Java Source Files Using Reflection

Have you ever needed to parse a Java source file, but didn't want to write a parser for it?  Well, you can by taking advantage of the Java compiler programmatically to compile the source files into class files then using a URLClassLoader load each class into memory and use reflection to get the information you need.  Let's take a look at how this works.

First you need to get a collection of all of the Java source files you wish to compile so that you can pass it to the compiler.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
File packageBaseDir = new File("path/to/the/base/dir/of/the/source/files");
List<File> sourceFiles = new ArrayList<>();

public void collectSourceFiles(File packageBaseDir, List<File> sourceFiles) {
    File[] filesInCurrDir = packageBaseDir.listFiles();

    for ( File file : filesInCurrDir ) {
        if ( file.isDirectory() ) {
            collectSourceFiles(file, sourceFiles);
        }
        else if ( file.getName().endsWith(".java") ) {
            sourceFiles.add(file);
        }
    }
}

Now that you have all of the source files, you need to access the Java compiler to compile them.

1
2
3
4
5
6
7
void compileSourceFiles(List<File> sourceFiles) {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        Iterable compilationUnits1 = fileManager.getJavaFileObjectsFromFiles(sourceFiles);
        JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, compilationUnits1);
        task.call();
}

The above code is accessing the Java compiler programmatically, using the StandardJavaFileManager to get the Java source as JavaFileObjects in order to pass to the compiler. A CompilationTask is created and then run on the source files. The source files should output to the same directory as the Java source. Now that the source is compiled, you can use a URLClassLoader to load the classes into your program.

1
2
3
URLClassLoader urlClassLoader = new URLClassLoader(
                    new URL[]{packageBaseDir.toURI().toURL()},
                    null);

Then you can simply load the class and start using the standard reflection methods on it.

1
2
Class clazz = urlClassLoader.loadClass(binaryClassName);
Methods[] methods = clazz.getDeclaredMethods(); // or whatever else you're interested in

Happy coding!

Wednesday, January 7, 2015

Setup UPS with Synology Disk Station and CentOS Linux Server via USB and Network

Setting up a UPS that will automatically cause a Synology DiskStation to enter safe mode and CentOS 7 server was fairly straightforward, however there was not a lot of information showing how to do this so I decided to write this post.

I will describe how to setup a UPS connected to a Synology Disk Station via USB which will notify a machine running CentOS and the upsmon service when UPS events occur so that they can respond to a power outage accordingly.  

DiskStation Setup

Connect your UPS to your Synology NAS using a USB cable.

Using built in support for a UPS Network Server on the Synology NAS (which uses NUT from www.networkupstools.org under the covers) setup is very easy.

Login to your DiskStation and go to the Control Panel.  Select the "Hardware and Power" icon and go to the "UPS" tab.  You should see something similar to the screen shown below.


Select "Enable UPS Support" to enable communication with the UPS via the USB cable.

You can optionally set a period of time before the NAS enters Safe Mode or leave the default which will cause the NAS to enter Safe Mode when the UPS battery reaches a low status.  Safe mode un-mounts all disks and stops all services to prevent data loss on your NAS.

Next, check the "Enable network UPS server" box.  Then click "Permitted DiskStations".  Even though it says "Permitted DiskStations", it will work with any machine running the NUT upsmon service.  Once you click on the "Permitted DiskStations" button you will be presented with a form to fill out the IP's of the servers you want to notify when the NAS you're on receives UPS events.


Enter the IP of the server that you want to receive the UPS events and click "OK".  Then "Apply" on the main UPS page.

Linux Server Setup (CentOS)

First you'll need to install nut via yum.

If you don't already have the epel repository in yum, you will need to install it.

yum install epel-release

Then you will need to install nut.

yum install nut

Once nut is installed you should have a nut user and group created by the installer.

Open /etc/ups/upsmon.conf.  We will need to update the configuration to allow it to listen for events from the Synology server.  Search for the "MONITOR" section.  You will need to update or add a line that looks like the following:

MONITOR ups@<ip of synology server>:3493 1 <user> <pass> slave

To get the user and pass values, SSH to your Synology NAS.  In the file located at /usr/syno/etc/ups/upsd.users it should specify the username and password.  Use those values in the MONITOR line on the Linux server.

Also, be sure to look at the "SHUTDOWNCMD"  in upsmon.conf and ensure it halts the system instead of shutting it completely down so that it will come up automatically after a power outage.  This is the default in the file so you shouldn't have to change anything.  In your Linux server machine BIOS you need to also ensure it is setup to automatically power on after the power is restored.

On your Linux machine you'll need to create a directory /var/run/nut.  Change ownership of the directory to user nut and group nut.

chown nut:nut /var/run/nut

Modify /lib/systemd/system and remove nut-server.service from the nut-monitor.service file if you are not running a nut server on the linux box as this will prevent it from starting upsmon.  Since this machine is setup as the slave, you probably won't be running a nut server so make sure you take the entry out.

Next you will need to add upsmon to startup when your server starts.  Go to /etc/systemd/system.  Create a symbolic link to the nut-monitor.service.

ln -s /lib/systemd/system/nut-monitor.service nut-monitor.service

Finally, run the following commands to enable the service to be run by systemctl.

systemctl daemon-reload
systemctl enable nut-monitor.service

That's it!  When you experience a power outage your UPS should kick on, communicate with your DiskStation to enter safe mode, and the DiskStation should communicate with the Linux server to halt it and when the power comes back up the DiskStation and Linux Server should automatically start back up.

Monday, January 7, 2013

Continuous Integration With Jenkins


In this post I'll be describing how to integrate Jenkins with a Maven project with a remote source code repository on Github.

Download and Run Jenkins
Starting up continuous integration with Jenkins is extremely simple thanks to the Winstone servlet container.  All you need to do is download jenkens.war at http://jenkins-ci.org/ and start it up with the command "java -jar jenkins.war".  You're now up and running on localhost port 8080.  Starting Jenkins will create a new folder in the home directory of the user running Jenkins named ".jenkins".  This folder will contain all of the jobs you create, plugins you install, a workspace for all the source it needs to build, and everything else it needs to run.

It is likely that Jenkins will be needed outside of your local environment so you could run it behind something like Apache as explained at the following URL:

https://wiki.jenkins-ci.org/display/JENKINS/Running+Jenkins+behind+Apache

Install Plugins
To use Jenkins with Maven you will need the Maven Integration plugin which comes with Jenkins already.

To use Jenkins with Github you will need the GitHub plugin which will also download the Jenkins GIT plugin and github-api plugin.  To ensure you have these plugins, go to the "Manage Jenkins" link and then click on the "Manage Plugins" link.

Check to ensure you have the plugins mentioned above installed


If you do not have any of the four required plugins, download them by going to the "Available" tab and placing a checkmark next to each plugin you need and then click the "Install without restart" or "Download now and install after restart".  Then restart Jenkins by using the "Prepare for Shutdown" link in the "Manage Jenkins" menu and then stop the process running Jenkins.  By clicking the "Prepare for Shutdown" link it will prevent Jenkins from kicking off new builds so that Jenkins can be safely shutdown after any currently executing builds finish.  Unfortunately, Jenkins doesn't shutdown the server automatically after builds finish so you'll have to either kill the process yourself or stop the process using whatever shutdown script you may have created.

Create a new job
Once Jenkins is back up you will need to create a new job to run your build.  In the Jenkins menu click the "New Job" link.  This will bring up a form that allows you to specify the job name and what type of project you have so that it can setup the appropriate configuration for your project.  Since we're assuming a Maven project for this post, we'll choose "Build a maven2/3 project" and give the job the name "Maven Test Build Job" and then hit "OK".



Configuring the Git Repo
Next you will need to specify where your source code is located if it is in a version control repository.  In this case we're going to select "Git".  *Ignore the error below, it should not appear if you entered a valid URL and it is able to connect to the repository.


You will need to fill out the "Github project" field with the URL to your repository and project select "Git" under "Source Code Management". Then fill out the Repository URL.  If you want to be able to commit changes back to the repository then you will need to specify the SSH URL to the repository as the "Repository URL".  Also, be sure that the machine you're setting up Jenkins on has an SSH key for authentication setup on Github.  Go to https://github.com/settings/ssh for more information about setting up your SSH key if you do not already have one setup.

Polling for changes in Repository
If you want Jenkins to automatically perform a build whenever a new commit occurs in the repository, you'll need to setup Jenkins to poll Github for changes.  Thankfully, this is also very easy to do.  You just check the "Poll SCM" box under "Build Triggers" and set a cron-like schedule to poll at a set interval as shown below.


Maven Build Settings
Under the "Build" section you will need to specify the location of your pom.xml and which goals and options you wish Maven to perform.  The pom.xml location is relative to your Jenkins workspace.  Jenkins creates a workspace for each job.  So you can go to the .jenkins folder and look for a folder in
"workspace/Maven Test Build Job".  This is where your Git repo will be downloaded to.


If you don't need to push anything back to the repository after each build, then you are done.  However, if you do then there is some more work you need to do.

(Optional) Commiting After Build
One of the quirky things about using the Github Plugin is that even if you specify the branch you want to build, the workspace will be set to "No Branch".  You can test this by going to your .jenkins/workspace/<your-repo-name> directory and doing a "git branch".  Notice the "*" isn't next to the branch you think it should be, it's next to no branch.

To remedy the situation you'll need to add a shell command to the "Pre Steps" section so that it does a checkout of the branch you want to commit to before it does the build.  Under "Pre Steps", select "Add pre-build step" and then pick "Execute Windows batch command" or "Execute shell".  A box will appear that will allow you type in your script.  Type in "git checkout <your-branch-name>".


Next you will need to add a "Post Step" that will commit the changes to the repository.  Under "Post Steps" choose if you want to run it only if the build succeeds, if it succeeds or is unstable, or regardless of the build result.  Then click "Add post-build step".  Again, choose "Execute Windows batch command" or "Execute shell".  A box will appear that will allow you type in your script.  Type in the following:

    git commit -m "<your comment>"
    git push



(Optional) Executing another job if current job is successful
In cases where the success of the current build should kick off another job, you'll need to setup a "Post-build Action".  Go under "Post-build Actions" and click the "Add post-build action" button.  Select "Build other projects" from the drop down menu.  This will prompt for a project to build.  Enter the name of the job you want this job to kickoff when successful.

Save your changes and your job is now ready to run.  Click the "Build Now" link in the Jenkins menu to kickoff the job.

Monday, November 26, 2012

Tomcat Java Options

On a Unix based system the easiest way to set custom Java options for Tomcat is by adding a file in the <CATALINA_HOME>/bin directory named setenv.sh.  The catalina.sh script checks for the existence of this file and executes it if it exists. Inside this file you would add something similar to the following:

export JAVA_OPTS="-server -Xms2048 -Xmx4096"


Monday, November 12, 2012

AspectJ with Maven and Eclipse Juno

This post will discuss how to use AspectJ with an already existing Maven project in Eclipse.  
First you need to start by downloading AJDT (AspectJ Development Tools) for Eclipse.  

Install AJDT As of this writing, the latest AJDT plugin can be found at:
http://download.eclipse.org/tools/ajdt/42/update.

Convert to AspectJ Project
After downloading and installing the plugin you will need to convert your project to an AspectJ project.  To do so, right click your project in the project explorer and under "Configure" select "Convert to AspectJ Project".  This doesn't stop it from being a Maven project, it simply adds AspectJ support to your project.  

Note: You can remove AspectJ support from your project by right clicking it in the project explorer, selecting "AspectJ Tools" and selecting "Remove AspectJ Capability".

Configure Where Aspects Are Stored
Aspects are by convention in src/main/aspect, but you can configure the plugin to look for aspects by specifying the paths within a .ajproperties file or via your project properties in the "AspectJ Build" pane under "Aspect Path".

Creating a Property File
By convention the property file should be located at your project root, but you can locate it wherever you want if you tell the plugin where to look for it.  Within your pom.xml an entry needs to be added to tell the plugin where to look for it.  Inside the configuration section of the aspectj-maven-plugin add an entry like the following:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifcatId>aspectj-maven-plugin</artifactId>
  <configuration>
    <options>
        ...
      <ajdtBuilderDefFile>src/main/resources</ajdtBuilderDefFile>
    </options>
  </configuration>
  ...
</plugin>

Weaving into 3rd Party Jars
If you are going to be weaving an aspect into a 3rd party class located in a jar file, you will need to add that jar file to your InPath.  Go to your project properties and go to the "AspectJ Build" pane.  There is an InPath tab which allows you to add any jar files you want your aspects woven with.

Configure pom.xml with AspectJ Configuration for Portability
The above is fine if you are the only one developing aspects for the project, however all of the configuration is within the plugin within the IDE so every person wanting to develop aspects for the project will have to configure it.  While developers should still install the AJDT plugin, they won't have to configure the IDE if you put the configuration within the .ajproperties file and pom.xml.  

Add AspectJ Dependency to pom.xml
Within the dependencies section of the pom.xml, add the following snippet:

<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.6.11</version>
</dependency>

Add AspectJ Maven Plugin Build to pom.xml
Within the build section of your pom.xml add the following snippet:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>aspectj-maven-plugin</artifactId>
  <version>1.4</version>
  <configuration>
    <weaveDependencies>
      <weaveDependency>
        <groupId>groupId of jar</groupId>
       <artifactId>name of jar/artifact id</artifactId>
      </weaveDependency>
    </weaveDependencies>
    <ajdtBuildDefFile>build.ajproperties</ajdtBuildDefFile>
  </configuration>
  <executions>
    <execution>
      <phase>process-source</phase>
      <goals>
        <goal>compile</goal>
      </goals>
    </execution>
  </executions>
</plugin>  

The weave dependency specifies the resources that should be woven with your aspects.  The ajdtBuildDefFile property tells the plugin where to look for the property file containing the directories to include with aspect sources and which ones to exclude.

This was mainly written from memory so if you have any issues or find any missing pieces please let me know.