Communicate Two Jar File [closed] - communication

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
First of all I am new in Java. I hope that you would interest on that question, but please make your answers as obvious as possible. And I will try to tell my problem in an open way.
I am using NetBeans. I want to communicate two jar files such a way that,lets i have two jars A and B. And they are both in process, that is they are executed separately and I see two opened window. In the window of jar A, it waits for a string from user and I write there "call B". Then in the window of jar B, it will say that "program A is called at ... ". I searched on Internet and I have found such staff;"java.util.jar.JarFile, Remote Method Invocation, Network Sockets etc". But I could not reach any result from them since i could not find understandable answers for beginners. So if you suggest one of them, please give me at least a small example showing how to use them.

For a simple form of communication you could use java.net.socket to communicate between the two jar files. This will allow you to have the "ping pong" effect you desire.
In programA you would setup the server socket and listen for a client to connect
try {
serverSocket = new ServerSocket(4567);
}
catch (IOException e) {
System.out.println("Could not listen on port: 4567");
System.exit(-1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
}
catch (IOException e) {
System.out.println("Accept failed: 4567");
System.exit(-1);
}
If the server is able to accept a client the clientSocket object will have the remote address and remote port set to that of the client.
After the server successfully establishes a connection with a client, it communicates with the client (program B) using this code:
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine, outputLine;
out.println("ping");
while ((inputLine = in.readLine()) != null) {
System.out.println("Program B says: " + inputLine);
out.println("server: " + inputLine);
if (inputLine.equals("quit"))
break;
}
Now you have written the logic for program A to be able to talk to program B you also need to create the client to be able to interact with it.
ProgramB:
Socket socket = new Socket("programb", 4567);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader sysIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("server: quit"))
break;
fromUser = sysIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
Then for good practice close the streams
out.close();
in.close();
sysIn.close()
socket.close();
And this should give you a basis to be able to talk between the two, you will probably need to implement some form of protocol (something to handle messages) on the server so that it outputs something useful
Reference: http://docs.oracle.com/javase/6/docs/api/java/net/Socket.html

Related

Connect Azure MI SQL View to MVC app as read only code first

One aspect of an ASP.net core (6) MVC app I am working on needs to query an SQL View that already resides in an Azure SQL MI.
I need to be able to query this SQL View to be able to retrieve the data based on user input but with the following conditions.
I cannot use Entity Framework.
The connection has to be read only.
This has to be database first.
As of yet I do not have access to this View or any of the tables it draws from. However I am expected to have code ready to plug a connection string into.
Unfortunately any resources I have been able to find don't seem to apply to my specific conditions. So any advice in what direction or approach would work best would be appreciated.
Those are by no means "silly" conditions. You didn't specify the language or the database but I'll make assumptions
I cannot use Entity Framework
Just use standard ado.net
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/ado-net-code-examples#sqlclient
(I know that Link only answers are frowned upon)
The connection has to be read only.
Ensure that the account you connect under is read only. In SQL Server this is achieved by making you a member of the db_datareader group. This is something that should be enforced by the DBA that gives you an account
This has to be database first.
That's not really relevant. Just use the linked sample code to read from the existing view.
Literal copy paste of code at the link above:
using System;
using System.Data;
using System.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString =
"Data Source=(local);Initial Catalog=Northwind;"
+ "Integrated Security=true";
// Provide the query string with a parameter placeholder.
string queryString =
"SELECT ProductID, UnitPrice, ProductName from dbo.products "
+ "WHERE UnitPrice > #pricePoint "
+ "ORDER BY UnitPrice DESC;";
// Specify the parameter value.
int paramValue = 5;
// Create and open the connection in a using block. This
// ensures that all resources will be closed and disposed
// when the code exits.
using (SqlConnection connection =
new SqlConnection(connectionString))
{
// Create the Command and Parameter objects.
SqlCommand command = new SqlCommand(queryString, connection);
command.Parameters.AddWithValue("#pricePoint", paramValue);
// Open the connection in a try/catch block.
// Create and execute the DataReader, writing the result
// set to the console window.
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("\t{0}\t{1}\t{2}",
reader[0], reader[1], reader[2]);
}
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}

Database connection pattern

I use mysql-native. This driver is suppport vibed's connection pool. On dlang newsgroup mysql-native developer Nick Sabalausky wrote:
"If you're using a connection pool, you shouldn't need to worry about closing the connection. The whole point is that the connections stay open until you need to use one again. When your program ends, then connections will close by themselves."
"You create the pool once (wherever/whenever you want to). Then, every time you want to use the database you obtain a connection by calling MySqlPool.lockConnection."
"Calling 'close' will always close the connection. If you got you connection from the pool, then it will automatically return to the pool when you're no longer using it. No need to do anything special for that."
The question about how pool should be done? I have read about singleton pattern and can't unserstand is it this case.
I wrote next code:
database class:
import std.stdio;
import std.string;
import mysql;
import vibe.d;
import config;
import user;
class Database
{
Config config;
MySqlPool mydb;
Connection connection;
this(Config config)
{
this.config = config;
mydb = new MySqlPool(config.dbhost, config.dbuser, config.dbpassword, config.dbname, config.dbport);
}
void connect()
{
if(connection is null)
{
connection = mydb.lockConnection();
}
scope(exit) connection.close();
}
}
users class/struct:
module user;
import mysql;
import vibe.d;
struct User
{
int id;
string login;
string password;
string usergroup;
}
void getUserByName(string login)
{
User user;
Prepared prepared = prepare(connection, `SELECT id, login, password, usergroup from users WHERE login=?`); // need to get connection accessible here to make request to DB
prepared.setArgs(login);
ResultRange result = prepared.query();
if (result.empty)
logWarn(`user: "%s" do not exists`, login);
else
{
Row row = result.front;
user.id = row[0].coerce!(int);
user.login = row[1].coerce!string;
user.password = row[2].coerce!string;
user.usergroup = row[3].coerce!string;
logInfo(`user: "%s" is exists`, login);
}
}
The problem that I can't understand what is proper way to getting access to connection instance. It seems that it's very stupid ideas to create every new database connection class inside users structure. But how to do it's in better way? To make Connection connection global? Is it's good? Or there is more correct way?
scope(exit) connection.close();
Delete that line. It's closing the connection you just received from the pool before the connect function returns. All you're doing there is opening a connection just to immediately close it again.
Change getUserByName to take a connection as an argument (typically as the first argument). Typically, whatever code needs to call getUserByName should either open a connection, or get a connenction from the pool via lockConnection, and then pass that connection to getUserByName and whatever other DB-related functions it needs to use. Then, after your code is done calling getUserByName (and whatever other DB functions it needs to call), you either just don't worry about the connection anymore and let your vibed fiber finish (if you're using vibed and got the connection from a pool) or you close the connection (if you did NOT get the connection from a vibed pool).
One way to do it is to pass the connection to your functions that need it. So you would refactor your getUserByName() to take connection as an argument.
Another alternative is to use the DAO pattern . Constructor of your DAO class would take the connection as one of the main parameters, and all the methods would use it to do the DB operation.

Download a file from a server with a BlackBerry app

I want to download a file from a server via the internet with a BlackBerry app.
It is not important which protocol is used: FTP, HTTP or something else would be fine. I just need the user to click "download" button and then the app downloads this file from a server.
I have no idea how it can be done. I have tried a few solutions. In one I need a HttpConnectorFactory but this is not in my API.
I have searched for an answer to my question for days, but I haven't found a solution that works.
Links to solutions I have tried:
How to download an html file in a BlackBerry application
https://stackoverflow.com/questions/6290988/downloading-a-pdf-file-from-a-webserver-in-blackberry-java-application
Networking Helper Class
try this -
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc = connFact.getConnection(your_url);
HttpConnection httpConn = (HttpConnection) connDesc.getConnection();
try {
httpConn.setRequestMethod(HttpConnection.GET);
InputConnection inputConn = (InputConnection) httpConn;
InputStream is = inputConn.openInputStream();
byte[] data =IOUtilities.streamToBytes(is);
//the value in data will be the bytes of your file.
// now if you want to save the file, you can do it here......
} catch (IOException e) {
e.printStackTrace();
}

TCPClient in asp.net mvc application

I have asp.net mvc app that shows varios events. All events stored in a database. But now, I have to load data from the database and remote program. This program have external service (this is simple program that listening specific TCP port and recieve a query and send xml back).
And, I wrote simple page for test that connects to external program. The code got from MSDN:
static string Connect(String server, String message)
{
try
{
// Create a TcpClient.
Int32 port = 9197;
TcpClient client = new TcpClient(server, port);
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
// Get a client stream for reading and writing.
// Stream stream = client.GetStream();
NetworkStream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
// Receive the TcpServer.response.
// Buffer to store the response bytes.
data = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
stream.Close();
client.Close();
return responseData;
}
catch (ArgumentNullException e)
{
//
}
catch (SocketException e)
{
//
}
}
This is my action:
public ActionResult GetData()
{
string query = "some query";
var response = Connect("192.168.0.1", query);
var model = ParseResponse(response);
return View(model);
}
I think this solution will reduce the perfomance.
What is best practicies to use TCPClient in ASP.NET MVC 3 app?
What you think about my code?
Any suggestions are welcome.
I think this solution will reduce the perfomance.
Well. All/most database operations are done over sockets. And you do not notice that, do you?
The most likely performance issues are:
Your server
Server location
Connection setup
The only thing I would do now is to build in checks in the client to monitor the response time and write to a log (or send an email) when the response times are too high.
Don't try to optimize performance until that happen.
Solutions for the above mentioned issues:
Refactor and optimize
Either put the server on the same lan or create a cache proxy server.
Use connection pooling instead of disconnecting the connections every time.
I think this solution will reduce the perfomance.
It's as any other remote request that your server does - an I/O intensive operation. So you could use an asynchronous controller and the asynchronous versions of the TcpClient methods. This way you won't be jeopardizing any worker threads on your server during the execution of the remote request.

Execute .NET application (no-install) from webpage (intranet) and pass argument(s)?

i built an intranet on .NET MVC. I'm also building a separate planning tool in Winforms (performance choice). I would now like to 'open' the planning tool from the intranet (IE7) and pass an argument (e.g. Workorder number) so I can display the planning for that specific item. Is this possible?
I have a .application file for the Winforms application. I'm also able to change everything on both the .NET MVC intranet and the Winforms planning tool.
You can't simply call the application from the HTML; that would be a security hole. However, you can have the application register to be able to handle these requests via the registry. You say "no-install", so this might be a problem. Maybe your app could modify the registry on the first load.
Anyway, the app would register to handle a specific protocol (like when you click on an itunes:// or ftp:// link).
Instead you'd have something like:
View workflow #3472
which then launches your app with the argument specified.
See http://msdn.microsoft.com/en-us/library/aa767914(VS.85).aspx . You say IE7, but this should work with other browsers, too, once the protocol is registered.
Yes you can do it.
private string _output = "";
public string Execute()
{
try
{
Process process = new Process();
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
process.StartInfo.FileName = "path to exe";
process.StartInfo.Arguments = "here you can pass arguments to exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
Process currentProcess = Process.GetCurrentProcess();
process.StartInfo.UserName = currentProcess.StartInfo.UserName;
process.StartInfo.Password = currentProcess.StartInfo.Password;
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
return _output;
}
catch (Exception error)
{
return "ERROR : " + error.Message;
}
}
private void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
_output += e.Data + Environment.NewLine;
}
}
It's a simple example. You can use different threads to read output and errors from exe.

Resources