TNSNAMES é uma "conexão-informação-abstração". É onde você esconde nomes de host, informações de failover, número de porta, nome de serviço e sabe-se lá o quê.
Por que você se conecta usando hostname, port e sid?
jdbc:oracle:thin:@testhost:2000:testdb
Ei! Porque você não está usando o TNSNAMES! Sua string de conexão é uma conexão HOST. Uma conexão de host vai direto para o host e não faz nenhum aviso do seu arquivo tnsnames.ora. (Você não instruiu o JDBC para procurar lá ...)
Em seguida, não é recomendado conectar-se a um banco de dados oracle especificando o SID. Em vez disso, especifique o SERVICE_NAME. (Para 12c, o SID não deve mais ser usado)
jdbc:oracle:thin:@testhost:2000/SERVICE_NAME
Para identificar o service_name de sua instância:
$sqlplus / as sysdba
SQL>show parameter service
Para utilizar o TNSNAMES for jdbc, dê uma olhada aqui
O ouvinte está LISTENING na porta 2000?
#netstat -tulpn | grep :2000
A instância tenta se registrar no listener com um valor de porta padrão de 1521. É chamado de registro de instância dinâmico . O registro no listener falhará ao usar um valor de porta não padrão. Para ajustar isso, o parâmetro init LOCAL_LISTENER entra na imagem assim:
$sqlplus / as sysdba
SQL>alter system set LOCAL_LISTENER='(ADDRESS =(PROTOCOL=TCP)(HOST=localhost)(PORT=2000);
Agora vai funcionar. 100%
Vá aqui para uma explicação detalhada do parâmetro LOCAL_LISTENER