Archive for the ‘Java’ Category
Java & MySQL 8.0.19
It’s the in-between term time and we’re all stuck at home. I decided to update the image for my Fedora 30 virtual machine. I had a work around to the update issue that I had encountered last October in Bug #96969 but it was not required with the current version. However, after updating from MySQL 8.0.17 to MySQL 8.0.19, I found that my Java connection example failed.
The $CLASSPATH
value was correct:
/usr/share/java/mysql-connector-java.jar:. |
The first error that I got was the my reference to MySQL JDBC driver was incorrect. The error message is quite clear:
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary. Cannot connect to database server: The server time zone value 'MDT' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support. |
I changed the MySQL Driver reference as instructed by the error message:
29 30 31 | // Create instance of MySQLDriver. Class.forName ("com.mysql.cj.jdbc.Driver").newInstance(); conn = DriverManager.getConnection (url, username, password); |
After the change, I got the following error while retesting my little MySQL Java driver connection test program. Initially, I thought this required a change in the Java environment but that wasn’t it.
Cannot connect to database server: The server time zone value 'MDT' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support. |
It required me to add the following line to my /etc/my.cnf configuration file, which synchronizes the database’s timezone with the operating system.
# Synchronize the MySQL clock with the computer system clock. default-time-zone='+00:00' |
Then, running my MySQL Driver connection test program worked like a charm. It returns the following:
Database connection established MySQLDriver Version [8.0.19] Database connection terminated |
Here’s the MySQL Connector Java code if you’d like to use the MySQLDriver.java
file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | // Import classes. import java.sql.*; /* You can't include the following on Linux without raising an exception. */ // import com.mysql.jdbc.Driver; public class MySQLDriver { public MySQLDriver() { /* Declare variables that require explicit assignments because they're addressed in the finally block. */ Connection conn = null; Statement stmt = null; ResultSet rset = null; /* Declare other variables. */ String url; String username = "student"; String password = "student"; String database = "studentdb"; String hostname = "localhost"; String port = "3306"; String sql; /* Attempt a connection. */ try { // Set URL. url = "jdbc:mysql://" + hostname + ":" + port + "/" + database; // Create instance of MySQLDriver. Class.forName ("com.mysql.cj.jdbc.Driver").newInstance(); conn = DriverManager.getConnection (url, username, password); // Query the version of the database. sql = "SELECT version()"; stmt = conn.createStatement(); rset = stmt.executeQuery(sql); System.out.println ("Database connection established"); // Read row returns for one column. while (rset.next()) { System.out.println("MySQLDriver Version [" + rset.getString(1) + "]"); } } catch (SQLException e) { System.err.println ("Cannot connect to database server:"); System.out.println(e.getMessage()); } catch (ClassNotFoundException e) { System.err.println ("Cannot find MySQL driver class:"); System.out.println(e.getMessage()); } catch (InstantiationException e) { System.err.println ("Cannot instantiate class:"); System.out.println(e.getMessage()); } catch (IllegalAccessException e) { System.err.println ("Illegal access exception:"); System.out.println(e.getMessage()); } finally { if (conn != null) { try { rset.close(); stmt.close(); conn.close(); System.out.println ("Database connection terminated"); } catch (Exception e) { /* ignore close errors */ } } } } /* Unit test. */ public static void main(String args[]) { new MySQLDriver(); } } |
As always, I hope this helps those who encounter similar problems.
DBeaver for PostgreSQL
I’m migrating my database classes from the Oracle database to the PostgreSQL database. Using the Oracle Express Edition has always required a virtualized image because students use Windows and Mac OS. Also, the university doesn’t like my use of a virtualized image. Virtualization imposes incremental cost on students to have high end laptops.
The available Docker images don’t typically support the Oracle Express Edition. That means there are licensing implications tied to Oracle.
As a committee, we decided to use PostgreSQL as our new database platform. We opted to use PostgreSQL over MySQL because it supports arrays and stored procedures. PostgreSQL PL/pgSQL are a solid implementation of stored procedures. While MySQL supports a stored procedure language, it effectively discourages using it.
We use sqlplus
, mysql
, or psql
Command-Line Interface (CLI) as the primary interface. That’s because CLI supports production-oriented deployment and DevOps practices. The Open Source DBeaver project provides a clean native GUI management console for PostgreSQL. DBeaver also supports other databases, which pgAdmin doesn’t.
You click the Download button from the DBeaver home page. It support Windows, Mac OS, and Linux distributions. I downloaded the Linux RPM package to my Downloads directory. You can run the RPM with the following syntax:
rpm -ivh dbeaver-ce-6.2.3-stable.x86_64.rpm |
It doesn’t check for dependencies. The installation is quick. You can verify that it’s installed with the following command:
which dbeaver |
It installs here:
/usr/bin/dbeaver |
If you failed to install the PostgreSQL JAR file, you’ll see the following error message:
It will look like the following on Linux:
You should have a user in the pg_hba.conf
file, like the following:
host all all 127.0.0.1/32 trust |
As always, I hope this helps those solving problems.
Java and Postgres
I wanted to get Java working with PostgreSQL to test some GUI interfaces on Linux. Figuring out the necessary JAR file for the JDBC was my first hurdle. I found it was postgreSQL-42-2.5.jar
file.
You can download it with the following command line:
wget https://jdbc.postgresql.org/download/postgresql-42.2.5.jar |
I downloaded it to a Java directory off the home/student directory. Then, I added the following CLASSPATH
to local java.env
environment file.
#!/usr/bin/bash # Set the Java CLASSPATH environment variable to include the JDBC jar file. export set CLASSPATH=/home/student/Java/postgresql-42.2.5.jar:. |
I sourced the postgresql-42.2.5.jar
file and I wrote the following JavaTest.java
program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* Import classes. */ import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.logging.Level; import java.util.logging.Logger; public class JavaTest { public static void main(String[] args) { /* Set default strings for the connection. */ String url = "jdbc:postgresql://localhost:5432/videodb"; String user = "student"; String password = "student"; /* Try the connection and statement. */ try { Connection conn = DriverManager.getConnection(url, user, password); Statement st = conn.createStatement(); ResultSet rs = st.executeQuery("SELECT VERSION()"); if (rs.next()) { System.out.println(rs.getString(1)); } /* Close the result set and statement. */ rs.close(); st.close(); } catch (SQLException e) { Logger logger = Logger.getLogger(JavaTest.class.getName()); logger.log(Level.SEVERE, e.getMessage(), e); } } } |
I compiled the JavaTest.java
program and tested it. It failed with the following error:
FATAL: Ident authentication failed for user - Unable to connect to PostgreSQL |
The failure occurred because I hadn’t allowed the connection in PostgreSQL’s pg_hba.conf
file. I changed the following line in my pg_hba.conf
file:
host all all 127.0.0.1/32 ident |
to
host all all 127.0.0.1/32 trust |
Then, I restarted the postgresql-11
service, like this:
systemctl restart postgresql-11.service |
The JavaTest
program ran successfully and returned:
PostgreSQL 11.5 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 9.1.1 20190503 (Red Hat 9.1.1-1), 64-bit |
You can extend the logic to output a comma-separated value file by leveraging the JDBC help page, like this:
/* Import classes. */ import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.logging.Level; import java.util.logging.Logger; /* Create class withonly a static method for runtime testing. */ public class JavaReturnSet { public static void main(String[] args) { /* Set default strings for the connection. */ String url = "jdbc:postgresql://localhost:5432/videodb"; String user = "student"; String password = "student"; /* Try the connection and statement. */ try { /* Set connection, statement, and result set. */ Connection conn = DriverManager.getConnection(url, user, password); Statement st = conn.createStatement(); /* Use the + to concatenate lines for query clarity. */ ResultSet rs = st.executeQuery("SELECT m.account_number\n" + ", CONCAT(c.last_name,', ',c.first_name)\n" + "FROM member m JOIN contact c\n" + "ON m.member_id = c.member_id"); /* Get query metadata for subsequent management of results. */ ResultSetMetaData rsmd = rs.getMetaData(); String line; while (rs.next()) { /* Initialize the line output for each row. */ line = ""; /* Process the columns. */ for (int i = 0; i < rsmd.getColumnCount(); i++) { if (rsmd.getColumnType(i + 1) == 12) { line = line + "\"" + rs.getString(i + 1) + "\""; } else { line = line + rs.getInt(i + 1); } /* Put a comma between output columns. */ if (i < rsmd.getColumnCount() - 1) { line = line + ","; } } System.out.println(line); } /* Close the result set and statement. */ rs.close(); st.close(); } catch (SQLException e) { Logger logger = Logger.getLogger(JavaReturnSet.class.getName()); logger.log(Level.SEVERE, e.getMessage(), e); } } } |
As always, I hope this helps those looking for a clean solution.
Postgres Print Debug Notes
A student asked how you print output from PL/pgSQL blocks. The student wanted to know if there was something like the following in Oracle’s PL/SQL programming language:
dbms_output.put_line('some string'); |
or, in Java programming the:
System.out.println("some string"); |
The RAISE NOTICE
is the equivalent to these in Postgres PL/pgSQL, as shown in the following anonymous block:
do $$ BEGIN raise notice 'Hello World!'; END; $$; |
It prints:
NOTICE: Hello World! |
You can write a hello_world function as a named PL/pgSQL block:
CREATE FUNCTION hello_world() RETURNS text AS $$ DECLARE output VARCHAR(20); BEGIN /* Query the string into a local variable. */ SELECT 'Hello World!' INTO output; /* Return the output text variable. */ RETURN output; END $$ LANGUAGE plpgsql; |
You can call it with the following:
SELECT hello_world(); |
It prints:
hello_world -------------- Hello World! (1 row) |
Here’s a full test case with stored procedure in PL/pgSQL:
-- Drop the msg table. DROP TABLE msg; -- Create the msg table. CREATE TABLE msg ( comment VARCHAR(400) ); -- Transaction Management Example. DROP PROCEDURE IF EXISTS testing ( IN pv_one VARCHAR(30) , IN pv_two VARCHAR(10)); -- Transaction Management Example. CREATE OR REPLACE PROCEDURE testing ( IN pv_one VARCHAR(30) , IN pv_two VARCHAR(10)) AS $$ DECLARE /* Declare error handling variables. */ err_num TEXT; err_msg INTEGER; BEGIN /* Log actdual parameter values. */ INSERT INTO msg VALUES (pv_one||'.'||pv_two); EXCEPTION WHEN OTHERS THEN err_num := SQLSTATE; err_msg := SUBSTR(SQLERRM,1,100); RAISE NOTICE 'Trapped Error: %', err_msg; END $$ LANGUAGE plpgsql; do $$ DECLARE lv_one VARCHAR(30) := 'INDIVIDUAL'; lv_two VARCHAR(19) := 'R11-514-34'; BEGIN RAISE NOTICE '[%]', lv_one; RAISE NOTICE '[%]', lv_two; CALL testing( pv_one := lv_one, pv_two := lv_two ); END $$; -- Query any logged results. SELECT * FROM msg; |
It prints:
DROP TABLE CREATE TABLE DROP PROCEDURE CREATE PROCEDURE psql:fixed.sql:61: NOTICE: [INDIVIDUAL] psql:fixed.sql:61: NOTICE: [R11-514-34] DO comment ----------------------- INDIVIDUAL.R11-514-34 (1 row) |
I hope this helps those looking for a solution.
Cassandra on Fedora 30
The first thing to do with Fedora 30 is to check what part of Apache Cassandra is installed. You can use the following rpm
command to determine that:
rpm -qa | grep cassandra |
My Fedora 30 returned the following values:
cassandra-java-libs-3.11.1-12.fc30.x86_64 cassandra-python2-cqlshlib-3.11.1-12.fc30.x86_64 cassandra-3.11.1-12.fc30.x86_64 python2-cassandra-driver-3.18.0-1.fc30.x86_64 |
Notably missing from the list of rpm
list is the cassandra-server
package. You install cassandra-server with the def utility:
dnf install -y cassandra-server |
You should get an installation log like the following for the cassandra-server
package:
Display detailed console log →
Last metadata expiration check: 0:26:07 ago on Wed 11 Sep 2019 09:10:08 PM MDT. Package cassandra-3.11.1-12.fc30.x86_64 is already installed. Dependencies resolved. =========================================================================================================================== Package Architecture Version Repository Size =========================================================================================================================== Installing: cassandra-server x86_64 3.11.1-12.fc30 fedora 180 k Installing dependencies: sigar x86_64 1.6.5-0.20.git58097d9.fc27 fedora 76 k Transaction Summary =========================================================================================================================== Install 2 Packages Total download size: 255 k Installed size: 738 k Is this ok [y/N]: y Downloading Packages: (1/2): sigar-1.6.5-0.20.git58097d9.fc27.x86_64.rpm 131 kB/s | 76 kB 00:00 (2/2): cassandra-server-3.11.1-12.fc30.x86_64.rpm 233 kB/s | 180 kB 00:00 --------------------------------------------------------------------------------------------------------------------------- Total 116 kB/s | 255 kB 00:02 Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : sigar-1.6.5-0.20.git58097d9.fc27.x86_64 1/2 Running scriptlet: sigar-1.6.5-0.20.git58097d9.fc27.x86_64 1/2 Running scriptlet: cassandra-server-3.11.1-12.fc30.x86_64 2/2 Installing : cassandra-server-3.11.1-12.fc30.x86_64 2/2 Running scriptlet: cassandra-server-3.11.1-12.fc30.x86_64 2/2 Verifying : cassandra-server-3.11.1-12.fc30.x86_64 1/2 Verifying : sigar-1.6.5-0.20.git58097d9.fc27.x86_64 2/2 Installed: cassandra-server-3.11.1-12.fc30.x86_64 sigar-1.6.5-0.20.git58097d9.fc27.x86_64 Complete! |
Fedora Magazine has a great Get Started with Apache Cassandra on Fedora article on all the steps required to setup clusters. This article only covers creating and enabling the Cassandra service, and setting up a single node Cassandra instance.
You start Cassandra with the following command as the root
user:
systemctl start cassandra |
You enable Cassandra with the following command as the root user:
systemctl enable cassandra |
It creates the following symlink:
Created symlink /etc/systemd/system/multi-user.target.wants/cassandra.service → /usr/lib/systemd/system/cassandra.service. |
You can connect to the Test cluster with the following command:
cqlsh |
You should see the following:
Connected to Test Cluster at 127.0.0.1:9042. [cqlsh 5.0.1 | Cassandra 3.11.1 | CQL spec 3.4.4 | Native protocol v4] Use HELP for help. |
You can see the options by typing the help
command:
Documented shell commands: =========================== CAPTURE CLS COPY DESCRIBE EXPAND LOGIN SERIAL SOURCE UNICODE CLEAR CONSISTENCY DESC EXIT HELP PAGING SHOW TRACING CQL help topics: ================ AGGREGATES CREATE_KEYSPACE DROP_TRIGGER TEXT ALTER_KEYSPACE CREATE_MATERIALIZED_VIEW DROP_TYPE TIME ALTER_MATERIALIZED_VIEW CREATE_ROLE DROP_USER TIMESTAMP ALTER_TABLE CREATE_TABLE FUNCTIONS TRUNCATE ALTER_TYPE CREATE_TRIGGER GRANT TYPES ALTER_USER CREATE_TYPE INSERT UPDATE APPLY CREATE_USER INSERT_JSON USE ASCII DATE INT UUID BATCH DELETE JSON BEGIN DROP_AGGREGATE KEYWORDS BLOB DROP_COLUMNFAMILY LIST_PERMISSIONS BOOLEAN DROP_FUNCTION LIST_ROLES COUNTER DROP_INDEX LIST_USERS CREATE_AGGREGATE DROP_KEYSPACE PERMISSIONS CREATE_COLUMNFAMILY DROP_MATERIALIZED_VIEW REVOKE CREATE_FUNCTION DROP_ROLE SELECT CREATE_INDEX DROP_TABLE SELECT_JSON |
Here’s my script that creates Cassandra keyspace, which is more or less a database. You use the USE
command to connect to the keyspace or database, like you would in MySQL. You do not have sequences in Cassandra because they’re not a good fit for a distributed architecture. Cassandra does not support a native procedural extension like relational databases. You must create User-defined functions (UDFs) by embedding the logic in Java.
This script does the following:
- Creates a keyspace
- Uses the keyspace
- Conditionally drops tables and functions
- Creates two tables
- Inserts data into the two tables
- Queries data from the tables
I also included a call to a UDF inside a query in two of the examples. One of the queries demonstrates how to return a JSON structure from a query. To simplify things and provide clarification of the scripts behaviors, the details are outlined below.
- The first segment of the script creates the keyspace, changes the scope to use the keyspace, conditionally drop tables, create tables, and insert values into the tables:
/* Create a keyspace in Cassandra, which is like a database in MySQL or a schema in Oracle. */ CREATE KEYSPACE IF NOT EXISTS student WITH REPLICATION = { 'class':'SimpleStrategy' ,'replication_factor': 1 } AND DURABLE_WRITES = true; /* Use the keyspace or connect to the database. */ USE student; /* Drop the member table from the student keyspace. */ DROP TABLE IF EXISTS member; /* Create a member table in the student keyspace. */ CREATE TABLE member ( member_number VARCHAR , member_type VARCHAR , credit_card_number VARCHAR , credit_card_type VARCHAR , PRIMARY KEY ( member_number )); /* Conditionally drop the contact table from the student keyspace. */ DROP TABLE IF EXISTS contact; /* Create a contact table in the student keyspace. */ CREATE TABLE contact ( contact_number VARCHAR , contact_type VARCHAR , first_name VARCHAR , middle_name VARCHAR , last_name VARCHAR , member_number VARCHAR , PRIMARY KEY ( contact_number )); /* Insert a row into the member table. */ INSERT INTO member ( member_number, member_type, credit_card_number, credit_card_type ) VALUES ('SFO-12345','GROUP','2222-4444-5555-6666','VISA'); /* Insert a row into the contact table. */ INSERT INTO contact ( contact_number, contact_type, first_name, middle_name, last_name, member_number ) VALUES ('CUS_00001','FAMILY','Barry', NULL,'Allen','SFO-12345'); /* Insert a row into the contact table. */ INSERT INTO contact ( contact_number, contact_type, first_name, middle_name, last_name, member_number ) VALUES ('CUS_00002','FAMILY','Iris', NULL,'West-Allen','SFO-12345'); /* Insert a row into the member table. */ INSERT INTO member ( member_number, member_type, credit_card_number, credit_card_type ) VALUES ('SFO-12346','GROUP','3333-8888-9999-2222','VISA'); /* Insert a row into the contact table. */ INSERT INTO contact ( contact_number, contact_type, first_name, middle_name, last_name, member_number ) VALUES ('CUS_00003','FAMILY','Caitlin','Marie','Snow','SFO-12346');
The following queries the member table:
/* Select all columns from the member table. */ SELECT * FROM member;
It returns the following:
member_number | credit_card_number | credit_card_type | member_type ---------------+---------------------+------------------+------------- SFO-12345 | 2222-4444-5555-6666 | VISA | GROUP SFO-12346 | 3333-8888-9999-2222 | VISA | GROUP
- Create a
concatenate
User-defined function (UDF) for Cassandra. The first step requires you to edit thecassandra.yaml
file, which you find in the/etc/cassandra/default.conf
directory. There is a single parameter that you need to edit, and it is theenable_user_defined_functions
parameter. By default the parameter is set tofalse
, and you need to enable it to create UDFs.If you open the
cassandra.yaml
file as theroot
user, you should find the parameter on line 987, like:983 984 985 986 987
# If unset, all GC Pauses greater than gc_log_threshold_in_ms will log at # INFO level # UDFs (user defined functions) are disabled by default. # As of Cassandra 3.0 there is a sandbox in place that should prevent execution of evil code. enable_user_defined_functions: false
After you make the edit, the
cassandra.yaml
file should look like this:983 984 985 986 987
# If unset, all GC Pauses greater than gc_log_threshold_in_ms will log at # INFO level # UDFs (user defined functions) are disabled by default. # As of Cassandra 3.0 there is a sandbox in place that should prevent execution of evil code. enable_user_defined_functions: true
After you make the change, you can create your own UDF. The following UDF formats the first, middle, and last name so there’s only one whitespace between the first and last name when there middle name value is null.
This type of function must use a
CALLED ON NULL INPUT
clause in lieu of aRETURNS NULL ON NULL INPUT
clause. The latter would force the function to return a null value if any one of the parameters were null./* Drop the concatenate function because a replace disallows changing a RETURNS NULL ON NULL INPUT with a CALLED ON NULL INPUT without raising an "89: InvalidRequest" exception. */ DROP FUNCTION concatenate; /* Create a user-defined function to concatenate names. */ CREATE OR REPLACE FUNCTION concatenate (first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR) CALLED ON NULL INPUT RETURNS VARCHAR LANGUAGE java AS $$ /* Concatenate first and last names when middle name is null, and first, middle, and last names when middle name is not null. */ String name; /* Check for null middle name. */ if (middle_name == null) { name = first_name + " " + last_name; } else { name = first_name + " " + middle_name + " " + last_name; } return name; $$;
Query the values from the contact
table with the UDF function in the SELECT
-list:
/* Query the contact information. */ SELECT member_number , contact_number , contact_type , concatenate(first_name, middle_name, last_name) AS full_name FROM contact; |
It returns the following:
member_number | contact_number | contact_type | full_name ---------------+----------------+--------------+-------------------- SFO-12345 | CUS_00001 | FAMILY | Barry Allen SFO-12345 | CUS_00002 | FAMILY | Iris West-Allen SFO-12346 | CUS_00003 | FAMILY | Caitlin Marie Snow |
Query the values from the contact
table with a JSON format:
/* Query the contact information and return in a JSON format. */ SELECT JSON contact_number , contact_type , concatenate(first_name, middle_name, last_name) AS full_name FROM contact; |
It returns the following:
[json] ------------------------------------------------------------------------------------------------- {"contact_number": "CUS_00001", "contact_type": "FAMILY", "full_name": "Barry Allen"} {"contact_number": "CUS_00002", "contact_type": "FAMILY", "full_name": "Iris West-Allen"} {"contact_number": "CUS_00003", "contact_type": "FAMILY", "full_name": "Caitlin Marie Snow"} |
Fedora SQL*Developer
After you download SQL Developer 18 on Fedora 27, you can install it with the yum
utility, like
yum install -y sqldeveloper-18.2.0.183.1748-1.noarch.rpm |
The installation should generate the following log file:
Last metadata expiration check: 2:26:23 ago on Sat 25 Aug 2018 07:10:16 PM MDT. Dependencies resolved. ================================================================================================ Package Arch Version Repository Size ================================================================================================ Installing: sqldeveloper noarch 18.2.0.183.1748-1 @commandline 338 M Transaction Summary ================================================================================================ Install 1 Package Total size: 338 M Installed size: 420 M Downloading Packages: Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : sqldeveloper-18.2.0.183.1748-1.noarch 1/1 Running scriptlet: sqldeveloper-18.2.0.183.1748-1.noarch 1/1 Verifying : sqldeveloper-18.2.0.183.1748-1.noarch 1/1 Installed: sqldeveloper.noarch 18.2.0.183.1748-1 Complete! |
After you install SQL Developer, you won’t be able to launch it. Attempts to launch it won’t raise an error message either. The problem is that there is a post-installation step, which requires you to configure the product.conf
file.
You can see the error by navigating to the /opt/sqldeveloper
directory. You will find the sqldeveloper.sh
file in that directory. You will see the error when you run the command as the root user from the command-line interface (CLI), as follows:
/opt/sqldeveloper/sqldeveloper.sh |
Oracle SQL Developer Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. Type the full pathname of a JDK installation (or Ctrl-C to quit), the path will be stored in /root/.sqldeveloper/18.2.0/product.conf |
You can find the Oracle home by searching for the rt.jar
file as the root
user. You use the following find
command syntax from the /
topmost directory.
find . -name rt.jar |
On Fedora 27, you should see the following absolute file name:
./usr/lib/jvm/java-1.8.0-openjdk-1.8.0.171-1.b10.fc27.x86_64/jre/lib/rt.jar |
You discard the /jre/lib
portion of the directory path and the rt.jar
file name to get the Java home’s fully qualified path. This should update the product.conf
file but if you have to change it manually you should edit the following file:
/root/.sqldeveloper/18.2.0/product.conf |
You need to configure the SetJavaHome
parameter value in the product.conf
file. The SetJavaHome
parameter needs to point to the Java home directory on your Fedora instance. It should look like this:
# # By default, the product launcher will search for a JDK to use, and if none # can be found, it will ask for the location of a JDK and store its location # in this file. If a particular JDK should be used instead, uncomment the # line below and set the path to your preferred JDK. # SetJavaHome /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.171-1.b10.fc27.x86_64 |
It’s possible that an attempt to launch SQL Developer by another user may have copied the product.conf
file into a local directory. You should change those manually by editing their respective product.conf
files. Assuming you attempted to launch SQL Developer by a student
user before you changed the root
user’s copy of the SQL Developer’s product.conf
file.
IT Salary Thought
During the holidays, I check salaries for my students and the IT industry overall. I’m never surprised by the reality, after all salaries pay for return on skills and effort. Here’s my annual look, which some may find unkind but reality is seldom kind.
Before looking at IT salaries, it seems like a good opportunity to first look at the overall job market for Millennials in the United States. AOL provides a great graphic of the median income for Millennials (those born between 1981 and 1997), which is $18,000 to $43,000 a year:
That’s a stark contrast to Forbes’ statistics on the top college baccalaureate degrees. In fact, the top five with the highest salary are between $58 to $67 thousand a year. They are:
- Computer Science ………… $66,800
- Engineering ………………… $65,000
- Mathematics & Statistics … $60,300
- Economics ………………….. $58,600
- Finance ……………………… $58,000
Computer science, applied computer science, and information technology are probably lumped into the first category. Information systems, exposure without real skills, is a management degree and probably opens positions equivalent to the business degree at $50 thousand a year. More or less, that’s a nine thousand dollar difference between having real skills and being able to talk the game and supervise technical resources. (The 10 hottest IT skills for 2015 are listed in Computerworld.)
There’s no surprise that Ruby, Objective C (iPhone, iPad, Mac OS X), Python, Java, C++ are at the top of the pyramid. Starting salaries in the Salt Lake area are higher for programmers college than they are for other computer science skill sets. In fact, my informal contacts peg them as starting at $70+ thousand. That’s higher than Forbes average for computer science. Here’s a visual on experienced programmers by language:
It seems fair to say that a computer science, applied computer science, and information technology degree with an emphasis in real programming skills is the best bet to pay off student loans. However, some will wait for politicians to do that for them, but really that’s quite unlikely, isn’t it?
Reality is always blunt. Reality also seems to frequently differs from what politicians say. After all, politicians pander to audiences, which generally means they say a great deal of nonsense. Nonsense like economics doesn’t matter, everyone should earn the same regardless of their education, skills, or work ethic. Aldous Huxley said it more elegantly when he said, “That all men are equal is a proposition to which, at ordinary times, no sane human being has ever given his assent.”
Eclipse, Java, MySQL
While I previously blogged about installing Netbeans 8, some of my students would prefer to use the Eclipse IDE. This post shows how to install and configure Eclipse IDE, include the mysql-connector-java.jar, and write Java to access the MySQL.
You can download Eclipse IDE and then open it in Fedora’s Archive Manager. You can use the Archive Manager to Extract the Eclipse IDE to a directory of your choice. I opted to extract it into my student
user’s home directory, which is /home/student
.
After extracting the Eclipse IDE, you can check the contents of the eclipse
directory with the following command:
ls -al eclipse |
You should see the following:
drwxrwxr-x. 8 student student 4096 May 8 22:16 . drwx------. 33 student student 4096 May 8 21:57 .. -rw-rw-r--. 1 student student 119194 Mar 20 07:10 artifacts.xml drwxrwxr-x. 11 student student 4096 May 8 22:16 configuration drwxrwxr-x. 2 student student 4096 Mar 20 07:10 dropins -rwxr-xr-x. 1 student student 78782 Mar 20 07:08 eclipse -rw-rw-r--. 1 student student 315 Mar 20 07:10 eclipse.ini -rw-rw-r--. 1 student student 60 Mar 17 15:11 .eclipseproduct drwxrwxr-x. 41 student student 4096 Mar 20 07:10 features -rwxr-xr-x. 1 student student 140566 Mar 20 07:08 icon.xpm drwxrwxr-x. 4 student student 4096 Mar 20 07:09 p2 drwxrwxr-x. 12 student student 40960 Mar 20 07:10 plugins drwxrwxr-x. 2 student student 4096 Mar 20 07:10 readme |
You can launch the Eclipse IDE with the following command-line from the eclipse
directory:
./eclipse & |
While you can run this from the /home/student/eclipse
directory, it’s best to create an alias for the Eclipse IDE in the student
user’s .bashrc
file:
# Set alias for Eclipse IDE tool. alias eclipse="/home/student/eclipse/eclipse" |
The next time you start the student
user account, you can launch the Eclipse IDE by entering eclipse
in the search box opened by clicking on the Activities menu.
The following steps take you through installing Eclipse on Fedora Linux, which is more or less the same as any Linux distribution. It’s very similar on Windows platforms too.
Eclipse Installation
- Navigate to eclipse.org/downloads web page to download the current version of the Eclipse software. Click the Linux 32 Bit or Linux 64 Bit link, as required for your operating system.
- Click the Green Arrow to download the Eclipse software.
- The next dialog gives you an option to open or save the software. Click the Open with radio button to open the archive file.
- This the Linux Archive Manager. Click the Extract button from the menu tab to open the archive file.
- This extract button on file chooser dialog to install Eclipse into the /home/student/eclipse directory. Click the Extract button to let the Archive Manager create a copy of those files.
- The Archive Manager presents a completion dialog. Click the Close button to close the Archive Manager.
After installing the Eclipse software, you can configure Eclipse. There are sixteen steps to setup the Eclipse product. You can launch the product with the
Eclipse Setup
You need to launch the Eclipse application to perform the following steps. The syntax is the following when you did create the alias mentioned earlier in the blog post:
eclipse & |
The following steps cover setting up your workspace, project, and adding the MySQL JDBC Java archive.
- The branding dialog may display for 30 or more seconds before the Eclipse software application launches.
- The Workspace Launcher opens first on a new installation. You need to designate a starting folder. I’m using
/home/student/workspace
as my Workspace. Click the OK button when you enter a confirmed workspace.
- After setting the Workspace Launcher, you open to the Eclipse Welcome page. Click second of the two icons on the left to open a working Eclipse environment. Alternatively, you can connect to Tutorials on the same page.
- From the developer view, click on the File menu option, the New option on the list, and the Java Project option on the floating menu. Eclipse will now create a new Java project.
- The New Java Project dialog lets you enter a project name and it also gives you the ability to set some basic configuration details. As a rule, you simply enter the Project Name and accept the defaults before clicking the Finish button.
- After creating the new Java project, Eclipse returns you to the Welcome page. Click second of the two icons on the left to open a working Eclipse environment.
- Now you should see the working environment. Sometimes it takes the full screen but initially it doesn’t. Navigate to the lower right hand side, and expand the window to full size.
- Now you should see the full screen view of the Eclipse working environment.
- Now you create a new Java class by navigating to the File menu options, then the New menu option, and finally choosing the Class floating menu.
- The New Java Class dialog requires you to provide some information about the Java object you’re creating. The most important thing is the Java class name.
- The only difference in this copy of the New Java Class dialog is that I’ve entered
HelloWorld
as the Java Class’s name. Click the Finish button when you’re done.
- Eclipse should show you the following
HelloWorld.java
file. It’s missing amain()
method. Add a static main() method to theHelloWorld.java
class source file.
- This form shows the changes to the
HelloWorld.java
file. Specifically, it adds the It’s missing amain()
method. Add a static main() method to theHelloWorld.java
class source file.
- You can click the green arrow from the tool panel or you can click the Run menu option and Run submenu choice to test your program.
1 2 3 4
// Class definition. public class HelloWorld { public static void main(String args[]) { System.out.println("Hello World."); }}
- The Save and Launch dialog tells you that you’re ready to test creating a copy of the Java class file. Click the OK button to continue.
- The results from your program are written to the Console portion of the Eclipse IDE. This concludes the setup of a workspace, project, and deployment of actual Java classes.
Hello World.
Add MySQL JDBC Library
The following instructions add the MySQL Library and demonstrate how to write Java programs that connect to the MySQL database. They also use the mysql
project.
- Navigate to the Project menu and choose the Properties menu option.
- The Properties menu option opens the Properties for the
mysql
project on the Order and Export tab. Click the Libraries tab to add an external library.
- In the Libraries tab click the Add Library… button on the right to add an external library.
- In the JAR Selection dialog, click on Computer in the Places list, then click on usr, click on share, and click on java. The Name list should now include
mysql-connector-java.jar
file, and you should click on it before clicking on the OK button.
- You create new Java class file by clicking on the File menu. Then, you choose the New menu option and the Class menu option from the floating menu.
- Enter
MysqlConnector
as the name of the new Java class file and click the Finish button to continue.
- Eclipse generates the shell of the
MysqlConnector
class as shown in the illustration to the left.
- You should replace the
MysqlConnector
class shell with the code below. Then, click the green arrow or the Run menu and Run menu option to compile and run the new MysqlConnector Java class file.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class MysqlConnector extends Object { public static void main(String[] args) { try { /* The newInstance() call is a work around for some broken Java implementations. */ Class.forName("com.mysql.jdbc.Driver").newInstance(); /* Verify the Java class path. */ System.out.println("===================="); System.out.println("CLASSPATH [" + System.getProperty("java.class.path") + "]"); System.out.println("===================="); } catch (Exception e) {} finally { /* Verify the Java class path. */ System.out.println("===================="); System.out.println("CLASSPATH [" + System.getProperty("java.class.path") + "]"); System.out.println("===================="); } } }
- The Save and Launch dialog informs you are saving a
MysqlConnector.java
file to yourmysql
project. Click the OK button to continue.
- The next screen shows that the program successfully connected to the MySQL database by printing the following information to the Console output tab.
==================== CLASSPATH [/home/student/Code/workspace/MySQL/bin:/usr/share/java/mysql-connector-java.jar] ==================== ==================== CLASSPATH [/home/student/Code/workspace/MySQL/bin:/usr/share/java/mysql-connector-java.jar] ====================
- Instead of repeating steps #5 through #10, the image displays the testing of the MysqlResults class file. The code follows below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
/* Import the java.sql.* package. */ import java.sql.*; /* You can't include the following on Linux without raising an exception. */ // import com.mysql.jdbc.Driver; public class MySQLResult { public MySQLResult() { /* Declare variables that require explicit assignments because they're addressed in the finally block. */ Connection conn = null; Statement stmt = null; ResultSet rset = null; /* Declare other variables. */ String url; String username = "student"; String password = "student"; String database = "studentdb"; String hostname = "localhost"; String port = "3306"; String sql; /* Attempt a connection. */ try { // Set URL. url = "jdbc:mysql://" + hostname + ":" + port + "/" + database; // Create instance of MySQL. Class.forName ("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection (url, username, password); // Query the version of the database, relies on *_ri2.sql scripts. sql = "SELECT i.item_title, ra.rating FROM item i INNER JOIN rating_agency ra ON i.item_rating_id = ra.rating_agency_id"; stmt = conn.createStatement(); rset = stmt.executeQuery(sql); System.out.println ("Database connection established"); // Read row returns for one column. while (rset.next()) { System.out.println(rset.getString(1) + ", " + rset.getString(2)); } } catch (SQLException e) { System.err.println ("Cannot connect to database server (SQLException):"); System.out.println(e.getMessage()); } catch (ClassNotFoundException e) { System.err.println ("Cannot connect to database server (ClassNotFoundException)"); System.out.println(e.getMessage()); } catch (InstantiationException e) { System.err.println ("Cannot connect to database server (InstantiationException)"); System.out.println(e.getMessage()); } catch (IllegalAccessException e) { System.err.println ("Cannot connect to database server (IllegalAccesException)"); System.out.println(e.getMessage()); } finally { if (conn != null) { try { rset.close(); stmt.close(); conn.close(); System.out.println ("Database connection terminated"); } catch (Exception e) { /* ignore close errors */ } } } } /* Unit test. */ public static void main(String args[]) { new MySQLResult(); } }
After you click the green arrow or the Run menu and Run menu option to compile and run the program, you should see the following output. That is if you’re using my
create_mysql_store_ri2.sql
andseed_mysql_store_ri2.sql
files.Database connection established I Remember Mama, NR Tora! Tora! Tora!, G A Man for All Seasons, G Around the World in 80 Days, G Camelot, G Christmas Carol, G I Remember Mama, G The Hunt for Red October, PG Star Wars I, PG Star Wars II, PG Star Wars II, PG The Chronicles of Narnia, PG Beau Geste, PG Hook, PG Harry Potter and the Sorcerer's Stone, PG Scrooge, PG Harry Potter and the Sorcer's Stone, PG Harry Potter and the Sorcer's Stone, PG Harry Potter and the Chamber of Secrets, PG Harry Potter and the Chamber of Secrets, PG Harry Potter and the Prisoner of Azkaban, PG Harry Potter and the Prisoner of Azkaban, PG Harry Potter and the Half Blood Prince, PG Star Wars III, PG-13 Casino Royale, PG-13 Casino Royale, PG-13 Die Another Day, PG-13 Die Another Day, PG-13 Die Another Day, PG-13 Golden Eye, PG-13 Golden Eye, PG-13 Tomorrow Never Dies, PG-13 Tomorrow Never Dies, PG-13 The World Is Not Enough, PG-13 Clear and Present Danger, PG-13 Clear and Present Danger, PG-13 Harry Potter and the Goblet of Fire, PG-13 Harry Potter and the Goblet of Fire, PG-13 Harry Potter and the Goblet of Fire, PG-13 Harry Potter and the Order of the Phoenix, PG-13 Harry Potter and the Deathly Hallows, Part 1, PG-13 Harry Potter and the Deathly Hallows, Part 2, PG-13 Brave Heart, R The Chronicles of Narnia, E MarioKart, E Need for Speed, E Cars, E RoboCop, M Pirates of the Caribbean, T Splinter Cell, T The DaVinci Code, T Database connection terminated
As always, I hope the note helps those trying to work with the Eclipse product.
Netbeans 8 – Fedora
Some of my students want to use the Fedora image that I built for my database classes in my Java software development life cycle course. As a result, they wanted a Java development environment installed. I examined JDeveloper 11g (11.1.1.7.0) and 12c (12.1.3) but resolved on the more generic Netbeans 8 (8.0.2) IDE.
JDK 7 with Netbeans 8 Download
You can download the generic Netbeans 8 IDE, the JDK 7 with Netbeans, or the JDK 8 with Netbeans for the Linux installation. After you download the executable program, you should follow these instructions to install the Netbeans 8 IDE on Fedora.
As the student
user, you can download the file to your ~student/Downloads
directory and then run these two commands:
chmod +x ./jdk-7u80-nb-8_0_2-linux-x64.sh sudo ./jdk-7u80-nb-8_0_2-linux-x64.sh |
It produces the following output log:
Configuring the installer... Searching for JVM on the system... Preparing bundled JVM ... Extracting installation data... Running the installer wizard... |
Then, it launches the installer. These screens show you how to install and create your first Java project.
JDK 7 with Netbeans 8 Installation
- The first installation dialog welcomes you to the JDK 7 Update and NetBeans 8 Installer. Click the Next button to proceed.
- The second installation dialog asks you to accept the terms in the license agreement. Click the Next button to proceed.
- The third installation dialog asks you to install Netbeans 8. Click the Browse button if you would like to install it in a different area. Click the Next button to proceed.
- The fourth installation dialog asks you to install another Java JDK 7 that supports the current release of Netbeans 8. Click the Browse button if you would like to install it in a different area. Click the Next button to proceed.
- The fifth installation dialog shows you the progress bar for installing Java JDK 7 that supports the current release of Netbeans 8. You may not need to click the Next button to proceed because it should progress to the Netbeans progress dialog. Click the Next button to proceed when it doesn’t do it automatically.
- The sixth installation dialog shows you the progress bar for installing Netbeans 8. Click the Next button to proceed when it doesn’t do it automatically.
- The next screen is the final screen of the Java SE Development Kit and NetBeans IDE Installer. Click the Finish button to complete the installation.
After the installation, you need to check if the netbeans
program can be found by users. It shouldn’t be found at this point because it isn’t in the default $PATH
environment variable.
Configuring the student
user
You can set the $PATH
variable dynamically like this:
export PATH=$PATH:/usr/local/netbeans-8.0.2/bin |
The netbeans
program location was set in Step #4 of the Netbeans installation. After setting the $PATH
environment variable, you can run netbeans
with this syntax:
./netbeans & |
However, the better approach is to put the following lines in your .bashrc
file. This change ensures that you can access the netbeans
program anytime you launch a Terminal session.
# Add netbeans to the user's PATH variable. export PATH=$PATH:/usr/local/netbeans-8.0.2/bin |
After you have configured the student
user’s .bashrc
file, you can now use Netbeans to create a Java project.
Create a new Netbeans project
- The next screen is the Netbeans 8 Start Page. This is where you can create your first Java development project.
- You click the File menu and then the New Project menu option to open a new project.
- It launches the New Project dialog at Step #1 – Choose Project, where you choose Java from your Categories list and Java Application from the Projects list. You click the Next button to continue.
- It launches the New Project dialog at Step #2 – Name and Location, where you enter a Project Name. The example uses
MySQLJava
as the project name. You click the Next button to continue.
- It launches the
MySQLJava.java
tab in the Netbeans 8 application. This is where you can enter your code.
After you successfully download the Java 7 SE and Netbeans 8, you should download JDK 8 with Netbeans 8 because Java 7 EOL (End-of-Life) is April 30th, 2015. You may think that you need to uninstall the JDK 7 with Netbeans 8 before you install the JDK 8 with Netbeans 8, but you don’t have to do so. When you install JDK 8 with Netbeans 8 into an environment with a preinstalled JDK 7 with Netbeans 8, the installer only adds the JDK 8.
The following segments of the post show you how to download and install JDK 8 with Netbeans 8, and how to configure Netbeans to work with the JDK 7 and JDK 8 as interchangeable libraries.
JDK 8 with Netbeans 8 Download
You can now download the JDK 8 with Netbeans for the Linux installation. After you download the executable program, you should follow these instructions to install it on Fedora.
As the student
user, you can download the file to your ~student/Downloads
directory and then run these two commands:
chmod +x ./jdk-8u45-nb-8_0_2-linux-x64.sh sudo ./jdk-8u45-nb-8_0_2-linux-x64.sh |
It produces the following output log:
Configuring the installer... Searching for JVM on the system... Preparing bundled JVM ... Extracting installation data... Running the installer wizard... |
Then, it launches the installer, which will be very similar to the steps you went through earlier. There are differences. There are only five screens that you navigate as opposed to the seven from the earlier JDK 7 with Netbeans 8 installation, as you’ll see below.
JDK 8 with Netbeans 8 Installation
- The first installation dialog welcomes you to the JDK 8 Update and NetBeans 8 Installer. Click the Next button to proceed.
- The second installation dialog installs the JDK 8. Click the Next button to proceed.
- The third installation dialog is a summary of what you’ll install. Click the Install button to proceed.
- The fourth installation dialog shows you a progress bar. You don’t need to do anything but watch the progress.
- The fifth installation dialog shows you the installation is complete. Click the Finish button to proceed when it doesn’t do it automatically.
After you have installed the JDK 8 SE, you can use Netbeans to add the JDK 8 platform.
Add the JDK 8 Platform to Netbeans 8
- After you open Netbeans 8, you choose the Tools menu choice. Then, you select the Java Platforms menu option.
- It launches the Java Platform Manager dialog. You click the Add Platform button to add the JDK 8 platform.
- It launches the Add Java Platform dialog. Leave the Java Standard Edition radio button checked. You click the Next button to proceed.
- It launches the Add Java Platform file chooser dialog. Here you navigate to find the JDK 8 software, which is located in
/usr/local/jdk1.8.0_45
directory.
- After selecting the
/usr/local/jdk1.8.0_45
directory as the platform folder, click the Next button to proceed.
- After setting the directory, you’re asked to verify the Java Platform information. If it’s correct, click the Finish button to proceed.
- After finishing the installation, you’ll see that you have two installed Java Platforms. Unfortunately, the first one installed is the default unless you modify the
netbeans.conf
file. You click the Close button to complete the process.
Set JDK 8 Platform as the Default Java Platform for Netbeans 8
After adding the JDK 8 Java Platform, you can change the default setting my manually editing the /usr/local/netbeans-8.0.2/etc/netbeans.conf
file. You simply remark out the line for JDK 7 and replace it with one for JDK 8, as shown below. The next time you boot the Netbeans application it uses Java 1.8.
# netbeans_jdkhome="/usr/local/jdk1.7.0_80" netbeans_jdkhome="/usr/local/jdk1.8.0_45" |
The next time you launch Netbeans 8, it will use JDK 8 because you set that as the default Java Platform
As always, I hope this helps those looking for information like this.
Java-MySQL Program
It turns out that configuring Perl wasn’t the last step for my student instance. It appears that I neglected to configure my student instance to support Java connectivity to MySQL. This post reviews the configuration of Java to run programs against MySQL. It also covers the new syntax on how you register a DriverManager
, and avoid Java compilation errors with the older syntax.
In prior posts, I’ve shown how to use Perl , PHP, Python, and Ruby languages to query a MySQL database on Linux.
You need to install the Open JDK libraries with the yum
utility command:
yum install -y java-1.7.0-openjdk* |
It should generate the following log output:
Loaded plugins: langpacks, refresh-packagekit Package 1:java-1.7.0-openjdk-1.7.0.75-2.5.4.2.fc20.x86_64 already installed and latest version Package 1:java-1.7.0-openjdk-headless-1.7.0.75-2.5.4.2.fc20.x86_64 already installed and latest version Resolving Dependencies --> Running transaction check ---> Package java-1.7.0-openjdk-accessibility.x86_64 1:1.7.0.75-2.5.4.2.fc20 will be installed --> Processing Dependency: java-atk-wrapper for package: 1:java-1.7.0-openjdk-accessibility-1.7.0.75-2.5.4.2.fc20.x86_64 ---> Package java-1.7.0-openjdk-demo.x86_64 1:1.7.0.75-2.5.4.2.fc20 will be installed ---> Package java-1.7.0-openjdk-devel.x86_64 1:1.7.0.75-2.5.4.2.fc20 will be installed ---> Package java-1.7.0-openjdk-javadoc.noarch 1:1.7.0.75-2.5.4.2.fc20 will be installed ---> Package java-1.7.0-openjdk-src.x86_64 1:1.7.0.75-2.5.4.2.fc20 will be installed --> Running transaction check ---> Package java-atk-wrapper.x86_64 0:0.30.4-4.fc20 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: java-1.7.0-openjdk-accessibility x86_64 1:1.7.0.75-2.5.4.2.fc20 updates 32 k java-1.7.0-openjdk-demo x86_64 1:1.7.0.75-2.5.4.2.fc20 updates 1.9 M java-1.7.0-openjdk-devel x86_64 1:1.7.0.75-2.5.4.2.fc20 updates 9.2 M java-1.7.0-openjdk-javadoc noarch 1:1.7.0.75-2.5.4.2.fc20 updates 14 M java-1.7.0-openjdk-src x86_64 1:1.7.0.75-2.5.4.2.fc20 updates 39 M Installing for dependencies: java-atk-wrapper x86_64 0.30.4-4.fc20 fedora 71 k Transaction Summary ================================================================================ Install 12 Packages (+1 Dependent package) Total download size: 163 M Installed size: 765 M Downloading packages: (1/6): java-1.7.0-openjdk-accessibility-1.7.0.75-2.5.4.2.f | 32 kB 00:00 (2/6): java-1.7.0-openjdk-demo-1.7.0.75-2.5.4.2.fc20.x86_6 | 1.9 MB 00:02 (3/6): java-1.7.0-openjdk-devel-1.7.0.75-2.5.4.2.fc20.x86_ | 9.2 MB 00:05 (4/6): java-1.7.0-openjdk-javadoc-1.7.0.75-2.5.4.2.fc20.no | 14 MB 00:04 (5/6): java-atk-wrapper-0.30.4-4.fc20.x86_64.rpm | 71 kB 00:00 (6/6): java-1.7.0-openjdk-src-1.7.0.75-2.5.4.2.fc20.x86_6 | 39 MB 00:23 -------------------------------------------------------------------------------- Total 4.5 MB/s | 163 MB 00:36 Running transaction check Running transaction test Transaction test succeeded Running transaction (shutdown inhibited) Installing : java-atk-wrapper-0.30.4-4.fc20.x86_64 3/13 Installing : 1:java-1.7.0-openjdk-accessibility-1.7.0.75-2.5.4.2.fc20 4/13 Installing : 1:java-1.7.0-openjdk-devel-1.7.0.75-2.5.4.2.fc20.x86_64 9/13 Installing : 1:java-1.7.0-openjdk-src-1.7.0.75-2.5.4.2.fc20.x86_64 10/13 Installing : 1:java-1.7.0-openjdk-javadoc-1.7.0.75-2.5.4.2.fc20.noarc 12/13 Installing : 1:java-1.7.0-openjdk-demo-1.7.0.75-2.5.4.2.fc20.x86_64 13/13 Verifying : 1:java-1.7.0-openjdk-demo-1.7.0.75-2.5.4.2.fc20.x86_64 2/13 Verifying : 1:java-1.7.0-openjdk-javadoc-1.7.0.75-2.5.4.2.fc20.noarc 3/13 Verifying : java-atk-wrapper-0.30.4-4.fc20.x86_64 5/13 Verifying : 1:java-1.7.0-openjdk-accessibility-1.7.0.75-2.5.4.2.fc20 6/13 Verifying : 1:java-1.7.0-openjdk-devel-1.7.0.75-2.5.4.2.fc20.x86_64 8/13 Verifying : 1:java-1.7.0-openjdk-src-1.7.0.75-2.5.4.2.fc20.x86_64 12/13 Installed: java-1.7.0-openjdk-accessibility.x86_64 1:1.7.0.75-2.5.4.2.fc20 java-1.7.0-openjdk-demo.x86_64 1:1.7.0.75-2.5.4.2.fc20 java-1.7.0-openjdk-devel.x86_64 1:1.7.0.75-2.5.4.2.fc20 java-1.7.0-openjdk-javadoc.noarch 1:1.7.0.75-2.5.4.2.fc20 java-1.7.0-openjdk-src.x86_64 1:1.7.0.75-2.5.4.2.fc20 Dependency Installed: java-atk-wrapper.x86_64 0:0.30.4-4.fc20 Complete! |
You can find the Java compiler’s version with the following command:
javac -version |
It should show you the following Java version:
javac 1.7.0_75 |
Next, you need to install the mysql-connector-java
library with yum
like this:
yum install -y mysql-connector-java |
It should generate the following installation output:
Loaded plugins: langpacks, refresh-packagekit mysql-connectors-community | 2.5 kB 00:00 mysql-tools-community | 2.5 kB 00:00 mysql56-community | 2.5 kB 00:00 pgdg93 | 3.6 kB 00:00 updates/20/x86_64/metalink | 15 kB 00:00 Resolving Dependencies --> Running transaction check ---> Package mysql-connector-java.noarch 1:5.1.28-1.fc20 will be installed --> Processing Dependency: jta >= 1.0 for package: 1:mysql-connector-java-5.1.28-1.fc20.noarch --> Processing Dependency: slf4j for package: 1:mysql-connector-java-5.1.28-1.fc20.noarch --> Running transaction check ---> Package geronimo-jta.noarch 0:1.1.1-15.fc20 will be installed ---> Package slf4j.noarch 0:1.7.5-3.fc20 will be installed --> Processing Dependency: mvn(log4j:log4j) for package: slf4j-1.7.5-3.fc20.noarch --> Processing Dependency: mvn(javassist:javassist) for package: slf4j-1.7.5-3.fc20.noarch --> Processing Dependency: mvn(commons-logging:commons-logging) for package: slf4j-1.7.5-3.fc20.noarch --> Processing Dependency: mvn(commons-lang:commons-lang) for package: slf4j-1.7.5-3.fc20.noarch --> Processing Dependency: mvn(ch.qos.cal10n:cal10n-api) for package: slf4j-1.7.5-3.fc20.noarch --> Running transaction check ---> Package apache-commons-lang.noarch 0:2.6-13.fc20 will be installed ---> Package apache-commons-logging.noarch 0:1.1.3-8.fc20 will be installed --> Processing Dependency: mvn(logkit:logkit) for package: apache-commons-logging-1.1.3-8.fc20.noarch --> Processing Dependency: mvn(avalon-framework:avalon-framework-api) for package: apache-commons-logging-1.1.3-8.fc20.noarch ---> Package cal10n.noarch 0:0.7.7-3.fc20 will be installed ---> Package javassist.noarch 0:3.16.1-6.fc20 will be installed ---> Package log4j.noarch 0:1.2.17-14.fc20 will be installed --> Processing Dependency: mvn(org.apache.geronimo.specs:geronimo-jms_1.1_spec) for package: log4j-1.2.17-14.fc20.noarch --> Processing Dependency: mvn(javax.mail:mail) for package: log4j-1.2.17-14.fc20.noarch --> Running transaction check ---> Package avalon-framework.noarch 0:4.3-9.fc20 will be installed --> Processing Dependency: xalan-j2 for package: avalon-framework-4.3-9.fc20.noarch ---> Package avalon-logkit.noarch 0:2.1-13.fc20 will be installed --> Processing Dependency: tomcat-servlet-3.0-api for package: avalon-logkit-2.1-13.fc20.noarch ---> Package geronimo-jms.noarch 0:1.1.1-17.fc20 will be installed ---> Package javamail.noarch 0:1.5.0-6.fc20 will be installed --> Running transaction check ---> Package tomcat-servlet-3.0-api.noarch 0:7.0.52-2.fc20 will be installed ---> Package xalan-j2.noarch 0:2.7.1-22.fc20 will be installed --> Processing Dependency: xerces-j2 for package: xalan-j2-2.7.1-22.fc20.noarch --> Processing Dependency: osgi(org.apache.xerces) for package: xalan-j2-2.7.1-22.fc20.noarch --> Running transaction check ---> Package xerces-j2.noarch 0:2.11.0-17.fc20 will be installed --> Processing Dependency: xml-commons-resolver >= 1.2 for package: xerces-j2-2.11.0-17.fc20.noarch --> Processing Dependency: xml-commons-apis >= 1.4.01 for package: xerces-j2-2.11.0-17.fc20.noarch --> Processing Dependency: osgi(org.apache.xml.resolver) for package: xerces-j2-2.11.0-17.fc20.noarch --> Processing Dependency: osgi(javax.xml) for package: xerces-j2-2.11.0-17.fc20.noarch --> Running transaction check ---> Package xml-commons-apis.noarch 0:1.4.01-14.fc20 will be installed ---> Package xml-commons-resolver.noarch 0:1.2-14.fc20 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: mysql-connector-java noarch 1:5.1.28-1.fc20 updates 1.3 M Installing for dependencies: apache-commons-lang noarch 2.6-13.fc20 fedora 281 k apache-commons-logging noarch 1.1.3-8.fc20 updates 78 k avalon-framework noarch 4.3-9.fc20 fedora 87 k avalon-logkit noarch 2.1-13.fc20 fedora 87 k cal10n noarch 0.7.7-3.fc20 fedora 37 k geronimo-jms noarch 1.1.1-17.fc20 fedora 32 k geronimo-jta noarch 1.1.1-15.fc20 fedora 21 k javamail noarch 1.5.0-6.fc20 fedora 606 k javassist noarch 3.16.1-6.fc20 fedora 626 k log4j noarch 1.2.17-14.fc20 fedora 449 k slf4j noarch 1.7.5-3.fc20 fedora 173 k tomcat-servlet-3.0-api noarch 7.0.52-2.fc20 updates 207 k xalan-j2 noarch 2.7.1-22.fc20 updates 1.9 M xerces-j2 noarch 2.11.0-17.fc20 updates 1.1 M xml-commons-apis noarch 1.4.01-14.fc20 fedora 227 k xml-commons-resolver noarch 1.2-14.fc20 fedora 108 k Transaction Summary ================================================================================ Install 1 Package (+16 Dependent packages) Total download size: 7.3 M Installed size: 10 M Downloading packages: (1/17): apache-commons-logging-1.1.3-8.fc20.noarch.rpm | 78 kB 00:00 (2/17): apache-commons-lang-2.6-13.fc20.noarch.rpm | 281 kB 00:00 (3/17): avalon-framework-4.3-9.fc20.noarch.rpm | 87 kB 00:00 (4/17): avalon-logkit-2.1-13.fc20.noarch.rpm | 87 kB 00:00 (5/17): cal10n-0.7.7-3.fc20.noarch.rpm | 37 kB 00:00 (6/17): geronimo-jms-1.1.1-17.fc20.noarch.rpm | 32 kB 00:00 (7/17): geronimo-jta-1.1.1-15.fc20.noarch.rpm | 21 kB 00:00 (8/17): javamail-1.5.0-6.fc20.noarch.rpm | 606 kB 00:00 (9/17): javassist-3.16.1-6.fc20.noarch.rpm | 626 kB 00:00 (10/17): log4j-1.2.17-14.fc20.noarch.rpm | 449 kB 00:00 (11/17): slf4j-1.7.5-3.fc20.noarch.rpm | 173 kB 00:00 (12/17): mysql-connector-java-5.1.28-1.fc20.noarch.rpm | 1.3 MB 00:01 (13/17): tomcat-servlet-3.0-api-7.0.52-2.fc20.noarch.rpm | 207 kB 00:00 (14/17): xalan-j2-2.7.1-22.fc20.noarch.rpm | 1.9 MB 00:00 (15/17): xerces-j2-2.11.0-17.fc20.noarch.rpm | 1.1 MB 00:00 (16/17): xml-commons-apis-1.4.01-14.fc20.noarch.rpm | 227 kB 00:00 (17/17): xml-commons-resolver-1.2-14.fc20.noarch.rpm | 108 kB 00:00 -------------------------------------------------------------------------------- Total 1.3 MB/s | 7.3 MB 00:05 Running transaction check Running transaction test Transaction test succeeded Running transaction (shutdown inhibited) Installing : xml-commons-apis-1.4.01-14.fc20.noarch 1/17 Installing : geronimo-jms-1.1.1-17.fc20.noarch 2/17 Installing : xml-commons-resolver-1.2-14.fc20.noarch 3/17 Installing : xerces-j2-2.11.0-17.fc20.noarch 4/17 Installing : xalan-j2-2.7.1-22.fc20.noarch 5/17 Installing : javamail-1.5.0-6.fc20.noarch 6/17 Installing : log4j-1.2.17-14.fc20.noarch 7/17 Installing : tomcat-servlet-3.0-api-7.0.52-2.fc20.noarch 8/17 Installing : avalon-framework-4.3-9.fc20.noarch 9/17 Installing : avalon-logkit-2.1-13.fc20.noarch 10/17 Installing : apache-commons-logging-1.1.3-8.fc20.noarch 11/17 Installing : javassist-3.16.1-6.fc20.noarch 12/17 Installing : cal10n-0.7.7-3.fc20.noarch 13/17 Installing : apache-commons-lang-2.6-13.fc20.noarch 14/17 Installing : slf4j-1.7.5-3.fc20.noarch 15/17 Installing : geronimo-jta-1.1.1-15.fc20.noarch 16/17 Installing : 1:mysql-connector-java-5.1.28-1.fc20.noarch 17/17 Verifying : geronimo-jta-1.1.1-15.fc20.noarch 1/17 Verifying : geronimo-jms-1.1.1-17.fc20.noarch 2/17 Verifying : xalan-j2-2.7.1-22.fc20.noarch 3/17 Verifying : apache-commons-lang-2.6-13.fc20.noarch 4/17 Verifying : slf4j-1.7.5-3.fc20.noarch 5/17 Verifying : log4j-1.2.17-14.fc20.noarch 6/17 Verifying : avalon-framework-4.3-9.fc20.noarch 7/17 Verifying : xerces-j2-2.11.0-17.fc20.noarch 8/17 Verifying : cal10n-0.7.7-3.fc20.noarch 9/17 Verifying : avalon-logkit-2.1-13.fc20.noarch 10/17 Verifying : 1:mysql-connector-java-5.1.28-1.fc20.noarch 11/17 Verifying : xml-commons-resolver-1.2-14.fc20.noarch 12/17 Verifying : xml-commons-apis-1.4.01-14.fc20.noarch 13/17 Verifying : javassist-3.16.1-6.fc20.noarch 14/17 Verifying : tomcat-servlet-3.0-api-7.0.52-2.fc20.noarch 15/17 Verifying : javamail-1.5.0-6.fc20.noarch 16/17 Verifying : apache-commons-logging-1.1.3-8.fc20.noarch 17/17 Installed: mysql-connector-java.noarch 1:5.1.28-1.fc20 Dependency Installed: apache-commons-lang.noarch 0:2.6-13.fc20 apache-commons-logging.noarch 0:1.1.3-8.fc20 avalon-framework.noarch 0:4.3-9.fc20 avalon-logkit.noarch 0:2.1-13.fc20 cal10n.noarch 0:0.7.7-3.fc20 geronimo-jms.noarch 0:1.1.1-17.fc20 geronimo-jta.noarch 0:1.1.1-15.fc20 javamail.noarch 0:1.5.0-6.fc20 javassist.noarch 0:3.16.1-6.fc20 log4j.noarch 0:1.2.17-14.fc20 slf4j.noarch 0:1.7.5-3.fc20 tomcat-servlet-3.0-api.noarch 0:7.0.52-2.fc20 xalan-j2.noarch 0:2.7.1-22.fc20 xerces-j2.noarch 0:2.11.0-17.fc20 xml-commons-apis.noarch 0:1.4.01-14.fc20 xml-commons-resolver.noarch 0:1.2-14.fc20 Complete! |
I must write too much Java code for the Windows platform because I didn’t notice the change in how the DriverManager
should be instantiated. Initially, I wrote the program using the following declaration for the DriverManager
class:
30 | DriverManager.registerDriver(new com.mysql.jdbc.Driver()); |
While it worked on Windows, the same syntax in the MySQL.java
program raised two errors on the Linux server. One for the declaration of the com.mysql.jdbc.Driver
class and another trying to declare an instance of Driver
class.
These are the two errors:
MySQL.java:5: error: package com.mysql.jdbc does not exist import com.mysql.jdbc.Driver; ^ MySQL.java:31: error: package com.mysql.jdbc does not exist DriverManager.registerDriver(new com.mysql.jdbc.Driver()); ^ |
I rewrote the MySQL.java
program as follows, and it works on both implementations:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | // Import classes. import java.sql.*; /* You can't include the following on Linux without raising an exception. */ // import com.mysql.jdbc.Driver; public class MySQL { public MySQL() { /* Declare variables that require explicit assignments because they're addressed in the finally block. */ Connection conn = null; Statement stmt = null; ResultSet rset = null; /* Declare other variables. */ String url; String username = "student"; String password = "student"; String database = "studentdb"; String hostname = "localhost"; String port = "3306"; String sql; /* Attempt a connection. */ try { // Set URL. url = "jdbc:mysql://" + hostname + ":" + port + "/" + database; // Create instance of MySQL. Class.forName ("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection (url, username, password); // Query the version of the database. sql = "SELECT version()"; stmt = conn.createStatement(); rset = stmt.executeQuery(sql); System.out.println ("Database connection established"); // Read row returns for one column. while (rset.next()) { System.out.println("MySQL Version [" + rset.getString(1) + "]"); } } catch (SQLException e) { System.err.println ("Cannot connect to database server:"); System.out.println(e.getMessage()); } catch (ClassNotFoundException e) { System.err.println ("Cannot connect to database server:"); System.out.println(e.getMessage()); } catch (InstantiationException e) { System.err.println ("Cannot connect to database server:"); System.out.println(e.getMessage()); } catch (IllegalAccessException e) { System.err.println ("Cannot connect to database server:"); System.out.println(e.getMessage()); } finally { if (conn != null) { try { rset.close(); stmt.close(); conn.close(); System.out.println ("Database connection terminated"); } catch (Exception e) { /* ignore close errors */ } } } } /* Unit test. */ public static void main(String args[]) { new MySQL(); } } |
The old approach to the DriverManager
and Driver
classes disallows the use of three of the exceptions in the sample code: ClassNotFoundException
, InstantiationException
, and IllegalAccessException
classes. The new syntax works on Linux, Mac OS X, and Windows. If you’re running on Mac OS X, you need to import the following additional library in the MySQL.java
program:
import com.apple.eawt.*; |
Before you compile the MySQL.java
program, you need to put the mysql-connector-java.jar
and your present working directory into your environment’s $CLASSPATH
variable. You can set the $CLASSPATH
variable at the command-line or embed the following in your .bashrc
file:
export CLASSPATH=/usr/share/java/mysql-connector-java.jar:. |
If you embedded it in the .bashrc
file, you need to source that file or restart your terminal session, which resources the .bashrc
for you. You can source your .bashrc
file from an active Terminal session in your home directory with this syntax:
. ./.bashrc |
If you’re new to Java and the MySQL Connector/J, you compile the MySQL.java
program with the following syntax. At least, it works when you have the MySQL.java
source file in the present working directory and want to create the class file in the same directory. You can find more about the javac command-line at the www.tutorialpoint.com web site>
javac -verbose -cp . MySQL.java |
Then, you can run it with the class file with this syntax:
java MySQL |
It should return the following:
Database connection established MySQL Version [5.6.24] Database connection terminated |
If you’d prefer to return data, you can replace line 34 in the MySQL.java
program with a query against a table, like:
34 | sql = "SELECT item_title, item_rating FROM item"; |
Then, change line 42 in the MySQL.java
program with syntax to manage the output, like:
42 | System.out.println(rset.getString(1) + ", " + rset.getString(2)); } |
Recompile it, and rerun the MySQL
class file with this syntax:
java MySQL |
It should return the following:
Database connection established The Hunt for Red October, PG Star Wars I, PG Star Wars II, PG Star Wars II, PG Star Wars III, PG13 The Chronicles of Narnia, PG RoboCop, Mature Pirates of the Caribbean, Teen The Chronicles of Narnia, Everyone MarioKart, Everyone Splinter Cell, Teen Need for Speed, Everyone The DaVinci Code, Teen Cars, Everyone Beau Geste, PG I Remember Mama, NR Tora! Tora! Tora!, G A Man for All Seasons, G Hook, PG Around the World in 80 Days, G Harry Potter and the Chamber of Secrets, PG Camelot, G Database connection terminated |
As always, I hope this helps those looking for a solution.