CentOS 6 repo Settings

To fix repo settings in CentOS 6

1. make sure there is no proxy or funny settings in
vi /etc/yum.conf

2. There are a couple of files within /etc/yum.repos.d/. Make sure the url are correct (accessible) and enabled=1
ll /etc/yum.repos.d/

3. Cleanup the repo, list and retest
yum –enablerepo=base clean metadata;
yum repolist all
yum search java-1.8.0-openjdk

Posted in Linux | Comments Off on CentOS 6 repo Settings

Show Linux Partition Tree Mountpoint and If SSD

1
lsblk -o TYPE,NAME,KNAME,UUID,MOUNTPOINT,SIZE,ROTA
Posted in Linux | Comments Off on Show Linux Partition Tree Mountpoint and If SSD

Setting log4j log level programmatically

Sometimes you don’t want to ship a log4j.properties file — you want to spin up logging in code. Useful inside unit tests, one-off debug runs, or anywhere you want to flip log levels at runtime. Here’s a self-contained setupLog4j() that wipes any existing config, installs a console appender with a pattern, sets the root level to DEBUG, and binds a logger for your class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;

private static void setupLog4j() {
        System.out.println("setupLog4j");
        BasicConfigurator.resetConfiguration();
        // Start clean.
        Logger.getRootLogger().removeAllAppenders();
        // Create appender
        ConsoleAppender console = new ConsoleAppender();
        // Configure the appender
        String PATTERN = "%d --[ %p ] %l: %m%n";
        console.setLayout(new PatternLayout(PATTERN));
        console.activateOptions();
        console.setName("stdout");
        Logger.getRootLogger().setLevel(Level.DEBUG);
        BasicConfigurator.configure(console);
        LOG = Logger.getLogger(MinerTest.class);
}

Replace MinerTest.class with your own class — it’s just the logger name (Log4j conventionally uses the fully-qualified class name so output stays organised by package).


A few useful additions.

This is Log4j 1.x — and Log4j 1.x is end-of-life. The package above is org.apache.log4j. Log4j 1.x reached EOL in August 2015 and has unpatched CVEs against it. If you’re starting something new, use Log4j 2 (org.apache.logging.log4j) or SLF4J with Logback. Keep this snippet around as a recipe for legacy projects, but don’t pick Log4j 1.x for anything fresh.

Set the level for one package, not the whole app. Logger.getRootLogger().setLevel(Level.DEBUG) turns DEBUG on globally — that floods everything, including third-party libraries. Usually you only want DEBUG for your own code:

1
2
Logger.getLogger("com.acme.miner").setLevel(Level.DEBUG);
Logger.getLogger("org.springframework").setLevel(Level.WARN); // tame the framework

Same idea in Log4j 2. The API is different — there’s no BasicConfigurator; instead you talk to the LoggerContext / Configurator:

1
2
3
4
5
6
7
8
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;

// Set the level for one package at runtime:
Configurator.setLevel("com.acme.miner", Level.DEBUG);

// Or for the root logger:
Configurator.setRootLevel(Level.DEBUG);

For the full “build a config from scratch” equivalent, see Log4j 2’s ConfigurationBuilder — the API is more verbose but lets you compose appenders, layouts, and loggers programmatically.

Using SLF4J / Logback? If your codebase logs via org.slf4j.Logger with Logback under the hood (very common), you flip levels through Logback’s own classes — SLF4J itself has no level-setting API:

1
2
3
4
5
6
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import org.slf4j.LoggerFactory;

Logger logger = (Logger) LoggerFactory.getLogger("com.acme.miner");
logger.setLevel(Level.DEBUG);

The cast from org.slf4j.Logger to ch.qos.logback.classic.Logger is the giveaway — SLF4J is just a facade; the level lives on the implementation. 🪵

Posted in java | Comments Off on Setting log4j log level programmatically

Print java stack trace from anywhere

Need to know which code calls a specific location? Dump the stack trace:

1
2
3
4
import org.apache.commons.lang3.exception.ExceptionUtils;

// ...somewhere in your method:
LOG.trace(ExceptionUtils.getStackTrace(new Throwable()));

You’re constructing a Throwable just to capture the current stack — you’re not throwing it. ExceptionUtils.getStackTrace turns the captured frames into a multi-line String that’s safe to hand to a logger. Make sure your log config has trace level enabled for whichever logger LOG belongs to, otherwise the line silently does nothing.


A few useful additions.

When this beats a breakpoint. You’d reach for this over a debugger when (a) you’re chasing a bug that only shows up in production, (b) the call happens in async / event-driven code where breakpoints are awkward, or (c) a method is called from many places and you want to know which path is firing. Sprinkle a few of these in, run the workload, then read the log.

No Apache Commons? Stdlib will do. ExceptionUtils lives in org.apache.commons.lang3, which is a separate dependency. If you don’t have it on the classpath you can fall back to plain JDK:

1
2
3
4
5
6
7
8
9
10
// Option 1 — quick and dirty, writes to stderr (not your logger):
new Throwable().printStackTrace();

// Option 2 — get the trace as a String you can log:
import java.io.StringWriter;
import java.io.PrintWriter;

StringWriter sw = new StringWriter();
new Throwable().printStackTrace(new PrintWriter(sw));
LOG.trace(sw.toString());

Java 9+: StackWalker is the modern API. If you actually want to inspect the frames programmatically (instead of just dumping a blob of text), use StackWalker — it’s lazy, so it doesn’t eagerly materialize every frame the way new Throwable().getStackTrace() does:

1
2
3
4
5
6
7
import java.lang.StackWalker;
import java.lang.StackWalker.StackFrame;
import java.util.stream.Collectors;

String trace = StackWalker.getInstance()
        .walk(s -> s.map(StackFrame::toString).collect(Collectors.joining("\n")));
LOG.trace(trace);

For a one-line debug print though, the original Apache Commons one-liner is still hard to beat. 🪵

Posted in java | Comments Off on Print java stack trace from anywhere

Knowing your exception class name

You’re staring at a generic catch (Exception e) and you don’t know which actual exception is being thrown. The trick is to log the runtime class so you can replace the generic catch with a specific one:

1
2
3
4
5
} catch (Exception e) {
    LOG.error("SQL error when processing " + requestId
        + ". Exception class: " + e.getClass().getCanonicalName());
    throw e;
}

Run the failing scenario, read the log, and you’ll see something like java.sql.SQLIntegrityConstraintViolationException — now you can write a specific catch for it.


A few useful additions.

Three flavours of class name. The Class object exposes three different name accessors and they behave differently for inner / anonymous classes:

  • getName() — JVM internal name. Inner classes show up with a dollar sign: com.acme.Outer$Inner.
  • getCanonicalName() — Java source-style name. Inner classes use a dot: com.acme.Outer.Inner. Returns null for anonymous and local classes.
  • getSimpleName() — just the leaf name, no package: Inner. Empty string for anonymous classes.

For diagnostics, getName() is usually safest because it never returns null. getCanonicalName() reads more naturally in logs but bites you the moment an exception comes from an anonymous class.

If you’re using SLF4J, you don’t need to format the exception yourself. Pass the throwable as the last argument and SLF4J logs the class name and the full stack trace for free:

1
2
3
4
} catch (Exception e) {
    LOG.error("SQL error when processing {}", requestId, e);
    throw e;
}

That single line gives you more diagnostic information than the original — no manual getClass() call needed.

Once you know the class, prefer multi-catch over a generic catch (Exception). Java 7+ supports listing several exception types in one block:

1
2
3
4
} catch (SQLIntegrityConstraintViolationException | DataAccessException e) {
    LOG.error("SQL error when processing {}", requestId, e);
    throw e;
}

This narrows what you’re handling, makes the intent obvious to readers, and lets your linter actually help you. The original “log the class name” trick is a great discovery tool — but once you’ve discovered, replace it with a specific catch. 🪲

Posted in java | Tagged | Comments Off on Knowing your exception class name

SELinux directory permission

To check SELinux directory permission you need to -z for example

1
ls -Z /var/www/html

If something is incorrect you can re-adjust some of the directory permission:

1
chcon -R -t httpd_sys_content_t /var/www/html
Posted in Linux, Operating System | Comments Off on SELinux directory permission

RedHat / Centos Firewall

To add an exception to firewall
In RedHat/CentOS 6

1
2
3
4
5
iptables --line -vnL
iptables -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.0.0/16 -j ACCEPT
iptables -D INPUT -p tcp -s 192.168.0.0/16 -j ACCEPT
service iptables save

In RedHat/CentOS 7

1
2
3
4
5
6
firewall-cmd --list-all
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-source=192.168.0.0/16
firewall-cmd --permanent --zone=public --remove-source=192.168.0.0/16
firewall-cmd --reload
systemctl disable firewalld
Posted in Linux, Operating System | Comments Off on RedHat / Centos Firewall

Bash string comparison

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
#!/bin/bash

function test(){
echo ""
echo "TEST $1"
echo "VAR_1: $VAR_1 VAR_2: $VAR_2 "
if [ "$VAR_1" = "false" ]; then echo " VAR_1 is false"; fi
if [ "$VAR_2" = "false" ]; then echo " VAR_2 is false"; fi
if [ "$VAR_1" = "false" ] || [ "$VAR_2" = "false" ]; then echo " At least one is false"; fi
}
VAR_1='true';
VAR_2='true';
test 1

VAR_1='true';
VAR_2='false';
test 2

VAR_1='false';
VAR_2='false';
test 3

function test2(){
echo ""
echo "TEST $1"
echo "VAR_3: $VAR_3 VAR_4: $VAR_4 "
[ -n "$VAR_3" ] && echo " VAR_3 is not null"
[ -z "$VAR_3" ] && echo " VAR_3 is null"
[ -n "$VAR_4" ] && echo " VAR_4 is not null"
[ -z "$VAR_4" ] && echo " VAR_4 is null"
}

VAR_3=""
VAR_4=""
test2 4

VAR_3="3"
VAR_4=""
test2 5
<h4>Result</h4>
$ /c/tmp/bashtest.sh

TEST 1
VAR_1: true VAR_2: true

TEST 2
VAR_1: true VAR_2: false
VAR_2 is false
At least one is false

TEST 3
VAR_1: false VAR_2: false
VAR_1 is false
VAR_2 is false
At least one is false

TEST 4
VAR_3: VAR_4:
VAR_3 is null
VAR_4 is null

TEST 5
VAR_3: 3 VAR_4:
VAR_3 is not null
VAR_4 is null
Posted in Bash, Linux | Comments Off on Bash string comparison

Show postgres lock

You’re staring at a query that won’t finish, or a deploy that hangs on a migration, or a UI request that just sits there. Postgres is almost certainly waiting on a lock that another transaction holds. The classic query for finding the culprit comes from the PostgreSQL wiki — it joins pg_locks against itself and against pg_stat_activity to show every blocked session and the session that’s blocking it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
SELECT blocked_locks.pid     AS blocked_pid,
       blocked_activity.usename  AS blocked_user,
       blocking_locks.pid    AS blocking_pid,
       blocking_activity.usename AS blocking_user,
       blocked_activity.query    AS blocked_statement,
       blocking_activity.query   AS current_statement_in_blocking_process
FROM pg_catalog.pg_locks         blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity
  ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks         blocking_locks
  ON blocking_locks.locktype       = blocked_locks.locktype
 AND blocking_locks.database       IS NOT DISTINCT FROM blocked_locks.database
 AND blocking_locks.relation       IS NOT DISTINCT FROM blocked_locks.relation
 AND blocking_locks.page           IS NOT DISTINCT FROM blocked_locks.page
 AND blocking_locks.tuple          IS NOT DISTINCT FROM blocked_locks.tuple
 AND blocking_locks.virtualxid     IS NOT DISTINCT FROM blocked_locks.virtualxid
 AND blocking_locks.transactionid  IS NOT DISTINCT FROM blocked_locks.transactionid
 AND blocking_locks.classid        IS NOT DISTINCT FROM blocked_locks.classid
 AND blocking_locks.objid          IS NOT DISTINCT FROM blocked_locks.objid
 AND blocking_locks.objsubid       IS NOT DISTINCT FROM blocked_locks.objsubid
 AND blocking_locks.pid           != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity
  ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted;

A few useful additions.

The modern shortcut: pg_blocking_pids. Since PostgreSQL 9.6 there’s a built-in function that does the same join in a single line — pg_blocking_pids(pid) returns an array of PIDs that are blocking the given PID. The whole “who’s blocking whom” query becomes:

1
2
3
4
5
6
7
8
SELECT a.pid                     AS blocked_pid,
       a.usename                 AS blocked_user,
       a.query                   AS blocked_statement,
       pg_blocking_pids(a.pid)   AS blocking_pids,
       a.wait_event_type,
       a.wait_event
FROM pg_stat_activity a
WHERE cardinality(pg_blocking_pids(a.pid)) > 0;

Shorter, easier to remember, and it handles fast-path locks correctly (the wiki query above can occasionally miss those). Use this on PG 9.6+ unless you specifically need the lock-type detail the wiki query produces.

How to read the result. blocked_pid is the session that’s stuck. blocking_pid is the one holding the lock. The catch: current_statement_in_blocking_process is whatever the blocker is running right now — often idle in transaction or some unrelated follow-up query, not the statement that originally took the lock. So if you see SELECT 1 in the blocker’s column, don’t be confused — the real cause is that this transaction has been holding locks for a while; the displayed query is just whatever it last ran. Look at state and xact_start in pg_stat_activity to see how long the transaction has been open.

Once you’ve found the blocker. Two functions, escalating in force:

1
2
3
4
5
-- Polite: ask the session to cancel its current query (transaction stays open)
SELECT pg_cancel_backend(12345);

-- Forceful: kill the entire backend connection (transaction rolls back)
SELECT pg_terminate_backend(12345);

pg_cancel_backend sends a SIGINT-like signal — the running statement is interrupted but the connection survives. pg_terminate_backend drops the whole connection. Try cancel first; reach for terminate when the session is wedged or holding locks while idle. Both require either superuser or membership in the pg_signal_backend role (PG 13+).

Don’t just kill — find out why. Killing the blocker stops the immediate pain, but if the same query keeps blocking everyone, the fix is upstream — a missing index, a transaction that stays open across a slow external call, an unbatched bulk update, or schema migrations during traffic. The query above shows you which session; the actual investigation usually lives in pg_stat_activity‘s state, xact_start, and application_name columns. 🔎

Posted in Database, PostgreSQL | Comments Off on Show postgres lock

Apache Lucene: The Search Engine Hiding Inside Half the Internet

If you’ve ever used Elasticsearch, Solr, or even some features in big platforms like Twitter or LinkedIn, chances are you’ve been touching Apache Lucene without knowing it. It’s the quiet workhorse — a Java library that does one thing extraordinarily well: full-text search. ☕

What Is Lucene?

Lucene is not a database, not a server, not a product you install. It’s a library — a JAR you drop into your Java application to add search capability. It handles indexing documents, parsing queries, scoring results by relevance, and giving you back ranked hits. Everything else (storage, networking, clustering) is left to you, which is exactly why projects like Elasticsearch and Solr wrap it: they add the operational layer on top of Lucene’s core search engine.

How Is It Different From Regular Search?

When you write SELECT * FROM articles WHERE body LIKE ‘%lucene%’, the database scans every row, character by character. It works, but it’s slow on millions of rows, and it can’t tell you which match is most relevant. A LIKE query doesn’t know that “running” and “runs” are related, or that an article mentioning “lucene” 12 times is probably more relevant than one that mentions it once.

Lucene flips the problem around with an inverted index. Instead of storing documents and scanning them, it stores a map of terms → documents containing those terms. Searching for “lucene” becomes a hash lookup, not a scan. On top of that, it:

  • Tokenizes and analyzes text — splits on whitespace, lowercases, strips punctuation, applies stemming (so “running” → “run”)
  • Scores by relevance using TF-IDF (or BM25 in newer versions) — documents with rarer matching terms rank higher
  • Supports fuzzy, wildcard, phrase, and boolean queries out of the box
  • Handles millions of documents with sub-millisecond query times

The Value Proposition

If your application has any user-facing search — product catalogs, document libraries, support tickets, log analysis, code search — rolling your own with SQL LIKE will eventually break. Lucene gives you Google-quality relevance ranking, fast queries on huge corpora, and a mature ecosystem, all from a single JAR. It’s the reason Elasticsearch became the de facto search backend for so many companies: Lucene under the hood, REST API on top. 💡

A Minimal Java Example

Here’s the classic “hello world” — index three documents in memory and search them:

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
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;

public class LuceneHello {
    public static void main(String[] args) throws Exception {
        Directory dir = new RAMDirectory();
        StandardAnalyzer analyzer = new StandardAnalyzer();

        // --- Index three documents ---
        IndexWriterConfig cfg = new IndexWriterConfig(analyzer);
        IndexWriter writer = new IndexWriter(dir, cfg);

        addDoc(writer, "Lucene is a Java full-text search library.");
        addDoc(writer, "Elasticsearch is built on top of Lucene.");
        addDoc(writer, "PostgreSQL has full-text search too, but differently.");
        writer.close();

        // --- Search ---
        DirectoryReader reader = DirectoryReader.open(dir);
        IndexSearcher searcher = new IndexSearcher(reader);
        Query query = new QueryParser("body", analyzer).parse("lucene");
        TopDocs hits = searcher.search(query, 10);

        System.out.println("Found " + hits.totalHits + " matches:");
        for (ScoreDoc sd : hits.scoreDocs) {
            Document d = searcher.doc(sd.doc);
            System.out.printf("  score=%.3f  %s%n", sd.score, d.get("body"));
        }
        reader.close();
    }

    private static void addDoc(IndexWriter w, String text) throws Exception {
        Document doc = new Document();
        doc.add(new TextField("body", text, Field.Store.YES));
        w.addDocument(doc);
    }
}

Run it and you’ll see two hits, ranked — the Lucene-focused sentence scores higher than the Elasticsearch one, because “lucene” appears more centrally and the document is shorter (so the term carries more weight).

A Fuzzier Query

Lucene’s query parser supports a tiny DSL. A DSL — short for Domain-Specific Language — is a small, purpose-built mini-language designed to do one thing well, as opposed to a general-purpose language like Java or Python that can do anything. SQL is a DSL for querying data, regex is a DSL for pattern matching, CSS selectors are a DSL for picking DOM elements. Lucene’s query syntax is a DSL for expressing search intent. (Not to be confused with the other DSL — Digital Subscriber Line — the telecom tech for internet over copper phone lines. Same acronym, completely unrelated worlds. ☎️)

The ~ operator gives you fuzzy matching (edit distance), and you can boost terms with ^:

1
2
3
4
5
6
7
8
9
10
11
// Matches "lucene", "lucine", "lucenne" — anything within edit distance 2
Query fuzzy = new QueryParser("body", analyzer).parse("lucenne~2");

// Boost "java" 3x, so docs mentioning java rank higher
Query boosted = new QueryParser("body", analyzer).parse("search java^3");

// Field-scoped phrase search — another bit of the DSL
Query phrase = new QueryParser("body", analyzer).parse("title:"full-text search"");

// Boolean combination
Query bool = new QueryParser("body", analyzer).parse("lucene AND java NOT solr");

That whole little grammar — the ~, the ^, the field:value prefix, the AND/OR/NOT keywords — is what makes it a DSL. You’re not writing Java to build queries; you’re writing a string in Lucene’s query language, and the QueryParser compiles it into Query objects for you.

That’s the whole pitch. If you’ve been getting by with SQL LIKE and your users are starting to complain that search “doesn’t find anything,” Lucene (or Elasticsearch on top of it) is almost certainly the next step. 🔍

Posted in java | Tagged , , | Comments Off on Apache Lucene: The Search Engine Hiding Inside Half the Internet