I'm trying to connect to my localhost kafka server from java function saved into Oracle database 19.3.
The problem is that i cannot reach the server. In database trace files i see that kafka library is using java.nio package to connect to server. Any connection attempt is ending with "Connection refused". I admit also that I can send data to topics from command line tool.
To check if my requests from database are incoming to localhost server at port 9092 i have run Hercules TCP Server and setup it to listen on this port. Then when i'm using my java function it nothing happens.
I write some "test" functions to make only simple connection to my local server, to see if there is some network problem.
The function where i use java.net package is working and i can see that i receive connection requests from database, but the function where i use java.nio package is returning always "Connection refused"
I have granted java.net.SocketPermission to my database user:
exec dbms_java.grant_permission( 'KAFKA', 'SYS:java.net.SocketPermission', '*', 'connect,resolve' );
commit;
Are there needed some special permissions to use java.nio package into oracle database java functions or maybe i'm doing something wrong?
Here are my java "test" functions code:
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "testTCP" AS
import java.net.Socket;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
public class testTCP {
public static String conn_nio(){
String response;
try {
InetSocketAddress hostAddress = new InetSocketAddress("localhost", 9092);
SocketChannel client = SocketChannel.open(hostAddress);
client.close();
response = "OK";
}
catch(Exception e){
response = "Message: " + e.getMessage() + " Cause: " + e.getCause();
}
return response;
}
public static String conn_net() {
String response;
try
{
Socket socket = new Socket( "localhost", 9092 );
socket.close();
response = "OK";
}
catch( Exception e )
{
response = "Message: " + e.getMessage() + " Cause: " + e.getCause();
}
return response;
}
}
Cannot reproduce. I pointed it to port 8080 of a local HTTP server which I started with
python -m SimpleHTTPServer 8080
and both connection methods are ok:
CREATE OR REPLACE FUNCTION test_net RETURN VARCHAR2 AS
LANGUAGE JAVA NAME 'testTCP.conn_net() return java.lang.String';
/
CREATE OR REPLACE FUNCTION test_nio RETURN VARCHAR2 AS
LANGUAGE JAVA NAME 'testTCP.conn_nio() return java.lang.String';
/
SELECT test_net FROM DUAL;
OK
SELECT test_nio FROM DUAL;
OK
Related
I am trying to host a web app on Openshift. I am using a websocket that handles all the connections. However,I am not sure what value to enter for my socket url. I have a .js file that reads:
...
// socket connection url and port
var socket_url = '192.168.8.102';
var port = '8080';
$(document).ready(function() {
$("#form_submit, #form_send_message").submit(function(e) {
e.preventDefault();
join();
});
});
var webSocket;
/**
* Connecting to socket
*/
function join() {
// Checking person name
if ($('#input_name').val().trim().length <= 0) {
alert('Enter your name');
} else {
name = $('#input_name').val().trim();
$('#prompt_name_container').fadeOut(1000, function() {
// opening socket connection
openSocket();
});
}
return false;
}
/**
* Will open the socket connection
*/
function openSocket() {
// Ensures only one connection is open at a time
if (webSocket !== undefined && webSocket.readyState !== WebSocket.CLOSED) {
return;
}
// Create a new instance of the websocket
webSocket = new WebSocket("ws://" + socket_url + ":" + port
+ "/WebMobileGroupChatServer/chat?name=" + name);
....
When i test it locally,it works perfectly using my local ip address of 192.168.8.102 as the socket_url. However, if I were to put my program up for online hosting,what value of socket_url should I enter instead? My domain name is http://jbosslew-weihao.rhcloud.com/
When I test it locally using tomcat apache server, the domain name is
http://192.168.8.102:8080/WebMobileGroupChatServer/
How do I find out the socket url of my server on openshift?
According to https://developers.openshift.com/en/managing-port-binding-routing.html you need to bind it to the port 8000 for regular access or to port 8443 for secure access
So your websockets url would be one of the following:
ws://app-domain.rhcloud.com:8000/path
wss://app-domain.rhcloud.com:8443/path
create mysql as service on Cloud Foundry and tunnel to mysql database
this provides me connection string to mysql database i pass that information to my app.
it works from my machine but when i deployed that app on Cloud Foundry server then it gives an error in connection
this is my connection code, tell me what needs to change to be deployed on Cloud Foundry
public class DB {
private static Connection connection = null;
public static Connection getConnection() {
String url = "jdbc:mysql://127.0.0.1:10100/db8dad2d02e114ef6bc9d24e68367e33e";
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(url,"uC0ag3NRJCT8c","p1nyZ38zadwfa");
System.out.println("Connect success fully");
return connection;
} catch (Exception e) {
System.out.println("Error");
System.out.println(e);
e.printStackTrace();
}
return null;
}
}
jayesh's answer is technically correct, but basically, the best way to deal with retrieving those information when inside a java app (assuming non-spring) is to use the cloudfoundry-runtime library: https://github.com/cloudfoundry/vcap-java/tree/master/cloudfoundry-runtime The README has examples of usage.
For completness, if using Spring, then things are even easier and chances are you don't even need to do anything special
Problem is here:
jdbc:mysql://127.0.0.1:10100
In this you're connecting to 127.0.0.1, it is a localhost, try giving the actual IP of your cloud server. Then it should work fine.
try {
String vcap_services = System.getenv("VCAP_SERVICES");
String hostname = "";
String dbname = "";
String user = "";
String password = "";
String port = "";
//for cloud config
if (vcap_services != null && vcap_services.length() > 0) {
JsonRootNode root = new JdomParser().parse(vcap_services);
JsonNode mysqlNode = root.getNode("mysql-5.1");
JsonNode credentials = mysqlNode.getNode(0).getNode(
"credentials");
dbname = credentials.getStringValue("name");
hostname = credentials.getStringValue("hostname");
user = credentials.getStringValue("user");
password = credentials.getStringValue("password");
port = credentials.getNumberValue("port");
String dbUrl = "jdbc:mysql://" + hostname + ":" + port + "/"
+ dbname;
System.out.println(dbUrl);
System.out.println(user + "password " + password);
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(dbUrl, user, password);
return connection;
} else {
//for local configuration
Class.forName("com.mysql.jdbc.Driver");
String url = jdbc:mysql://127.0.0.1:10100/db8dad2d02e114ef6bc9d24e68367e33e
connection = DriverManager.getConnection(url, "user name",
"password");
return connection;
}
} catch (Exception e) {
e.printStackTrace();
}
You're using information from vmc tunnel to try to connect. This is not going to work on the Cloud. You need to do what jayesh shows, and read the connection credentials from the Cloud Foundry environment instead. Eric's answer is even more complete :-)
I have the same problem. You must notice that "10100" is a port fortwarding to the mysql remote service.
you could use this just locally.Deploying your program locally with your database connection pointing to the forwarding port (101100).
But this won't work when you push your war to the Cloud Foundry Instance-
One solution is to use Spring based cloud beans. In my case i don't wan't to use this approach so i'm trying another solution...
I don't know if with the credentials (user, password, tc) created for the remote connection you could stablish a connection once you pushed your war to Cloud Foundry changing the forwarding port and using the default mysql port (3360)
In my case i don't want to use Spring Cloud Beans because the production application won't be deployed into a cloud storage.
i have this code to download a single file .
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTPClient;
public class NetTest {
public static void main(String[] args){
FTPClient client = new FTPClient( );
OutputStream outStream;
try {
this is the part of server and passwords .
client.connect( "servername" );
client.login("noman123", "pass");
String remoteFile = "/a.txt";
outStream = new FileOutputStream( "a.txt" );
simple fill downloading but error on this line
client.retrieveFile( remoteFile, outStream );
} catch(IOException ioe) {
System.out.println( "Error communicating with FTP server." );
} finally {
try {
client.disconnect( );
} catch (IOException e) {
System.out.println( "Problem disconnecting from FTP server" );
}
}
}
}
and it gives me errors like
i hope that u can understand the issue that i m facing now
java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
at java.io.BufferedWriter.flush(BufferedWriter.java:254)
at org.apache.commons.net.ftp.FTP.__send(FTP.java:496)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:470)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:547)
at org.apache.commons.net.ftp.FTP.port(FTP.java:872)
at org.apache.commons.net.ftp.FTPClient.openDataConnection(FTPClient.java:667)
at org.apache.commons.net.ftp.FTPClient.retrieveFile(FTPClient.java:1595)
at FtpDownloadDemo.main(FtpDownloadDemo.java:25)
turn off the firewall.in this issue
Make sure you can ping the server and log in manually, but assuming you're ok there, there's two additional things I would do.
1) Per the FTP Client documentation, check that you're really connected
// After connection attempt, you should check the reply code to verify success.
reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply))
{ // print more complete error }
There's a full example here.
2) It could be since you're trying to get the remote file "/a.txt" you're trying to get to the root directory and your ftp server isn't set up to allow you access. Try just "a.txt" in whichever directory your ftp client is set to dump a user into.
The documentation on the given example code that you should call the enterLocalPassiveMode method of FTPClient if you are behind a firewall.
read this article http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7077696
WORK AROUND to solve this problem start program with
-Djava.net.preferIPv4Stack=true
I have written a Java Program and the program connects to a database on my server, to find records, write records, update and delete. for some reason finding records works, but most of the time when i try to save or write a record it gives an error message saying:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 9,787 milliseconds ago. The last packet sent successfully to the server was 8,183 milliseconds ago.
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2552)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002)
... 46 more
Can anyone explain why this is happening?
Usuually this gives me the error message when trying to add a record, after i had the software running for more than about half a minute. seems to loose connection or something. when i run the program and quickly write a new record, it works
I was having the same sort of issue. I referred many post and comments but the thing worked for me was changing some parameters of the my.cnf file. Hope it will help you also ....
Set following parameters in my.cnf [mysqld] section
interactive_timeout=180 # "No.of sec. a server waits for activity on interactive connection before closing it"
wait_timeout=180 # "No. of sec. a server waits for an activity on a connection before closing it"
max_connect_errors=9999 # "More than this number of interrupted connections from a host this host will be blocked from further connections"
skip-name-resolve # "Don't resolved host names. All host names are IP's"
Sometimes this problem comes due to size of system RAM.May be you are inserting the data using buffer through RAM. To get out of this problem.
Set the Auto commit disable before inserting the data.
insert some amount of data appropriate to your System RAM (not the
whole).
Commit the query.
Do the steps 2 and 3 again until the whole insertion will not be
done.
You can understand this by the following code.
public static void main(string args[])
{
Connection con = null;
Statement stm = null;
int i;
float ratio;
ratio=1.0f;
try
{
Class.forName("com.mysql.jdbc.Driver");
// Connecting to the database
con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/demo",
"ashish", "impetus");
File f = new File("filler"); // taking the random text data from the file
// filler.txt and inserting that string
// in filler field of the relations
RandomAccessFile r = new RandomAccessFile(f,"r");
Random randomGenerator = new Random();
String strLine=new String();
int r1,flag=0;
stm = con.createStatement();
con.setAutoCommit(false) ;
int k=0;
i=0;
long sum2=0;
while(k%50000==0)
{
final long start = currentTimeMillis();
final StringBuilder builder =
new StringBuilder("INSERT INTO accounts
(aid, bid,abalance,filler) VALUES ");
while(i!=naccounts*ratio*scale )
{
int j=i+1;
for(int l=0;l<40;l++)
{
strLine+=((char)r.read());
r.skipBytes(0);
}
r1=randomGenerator.nextInt(1500);
if(strLine.equals(""))
{
flag=1;
}
if(flag!=1)
{
strLine=strLine.replaceAll("\\s","");
strLine=strLine.replaceAll("\\t","");
}
flag=0;
if (i%50000!=0)
{
builder.append(",");
}
builder.append(format("(%s, %s, %s, '%s')", j,
i/naccounts+1, 0, strLine));
strLine="";
r.seek(r1);
i++;
if(i%50000==0||i>=naccounts*ratio*scale)
{
final String query = builder.toString();
final PreparedStatement statement1 = con.prepareStatement(query);
statement1.execute();
con.commit();
final long stop= currentTimeMillis();
sum2=sum2+(stop-start);
statement1.close();
}
if(i%50000==0||i>=naccounts*ratio*scale)
{
break;
}
}
k=k+50000;
if(k>naccounts*ratio*scale)
{
break;
}
}
System.out.println(i+" rows inserted accounts table ");
System.out.println("time taken = "+sum2+" milliseconds");
}
catch (SQLException e)
{
System.out.println("Connection Failed! Check output console");
e.printStackTrace();
return;
}
catch (Exception e)
{
e.printStackTrace();
}
}
Did you follow/read this tutorial :
Connectivity with MYSQL
You have a part for your exception which can be useful for you.
I will quote something about your specific exception, just try that :
If you get a SQLException: Connection refused or Connection timed out
or a MySQL specific CommunicationsException: Communications link
failure, then it means that the DB isn't reachable at all. This can
have one or more of the following causes:
IP address or hostname in JDBC URL is wrong. Hostname in JDBC URL is
not recognized by local DNS server. Port number is missing or wrong in
JDBC URL. DB server is down. DB server doesn't accept TCP/IP
connections. DB server has run out of connections. Something in
between Java and DB is blocking connections, e.g. a firewall or proxy.
To solve the one or the other, follow the following advices:
Verify and test them with ping. Refresh DNS or use IP address in JDBC
URL instead. Verify it based on my.cnf of MySQL DB. Start the DB.
Verify if mysqld is started without the --skip-networking option.
Restart the DB and fix your code accordingly that it closes
connections in finally. Disable firewall and/or configure
firewall/proxy to allow/forward the port.
We would like to identify and display the server and port that a Java application is running on that is behind a proxy web server. This means that getServerName() and getServerPort() return the server name of the proxy and its port (80).
We have two application server instances running on a single physical box and therefore have two active ports per box i.e. 9080, 9081. What I'd like to have is <Application Server Name>:<Application Server Port> displayed.
Any ideas? I'm a complete Java noob, sorry if this is a basic question.
The server hostname is part of the request, as it depends on what URL the client used to reach your host. The value you get in this way is defined on the client and does not have to be what you expect.
If you are interested in the local hostname, you can try:
String hostname = InetAddress.getLocalHost().getHostName();
You can use ServletRequest#getLocalXXX() methods for this.
ServletRequest#getLocalName() returns local hostname.
ServletRequest#getLocalAddr() returns local IP.
ServletRequest#getLocalPort() returns local port.
Crunchify provides a nice example for this.
import java.net.InetAddress;
import java.net.UnknownHostException;
public class CrunchifyGetIPHostname {
public static void main(String[] args) {
InetAddress ip;
String hostname;
try {
ip = InetAddress.getLocalHost();
hostname = ip.getHostName();
System.out.println("Your current IP address : " + ip);
System.out.println("Your current Hostname : " + hostname);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}