I'm trying to pull all the data from a table using SELECT * from book, but I'm getting:
Attempt to invoke interface method 'java.sql.ResultSet java.sql.Statement.executeQuery(java.lang.String)' on a null object reference
I got it working when triggering the SQL statement in Eclipse. I'm trying to recreate it in Android Studio, but seems to throw this issue. Any help is appreciated.
SQL.java
package com.example.andy.loginapp;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/**
* Created by Andy on 1/4/2017.
*/
public class SQL {
private Statement st;
private Connection con;
private ResultSet rs;
public SQL(){
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/sqltest", "root", "");
st = con.createStatement();
}
catch(Exception e){
System.out.println(e);
}
}
public void getData(){
try{
String query = "SELECT * from book";
String queryInsert = "INSERT into Book " + "VALUE(authorField.getText(), titleField.getText(), yearField.getText())";
rs = st.executeQuery(query);
while(rs.next()){
String author = rs.getString("author");
String title = rs.getString("title");
System.out.println("Author: " + author + " " + "Title" + " " + title);
}
}
catch(Exception e){
System.out.println(e);
}
System.out.println("success");
}
}
MainActivity.java
package com.example.andy.loginapp;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutCompat;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.w3c.dom.Text;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class MainActivity extends AppCompatActivity {
private Statement st;
private Connection con;
private ResultSet rs;
TextView hi;
RelativeLayout background;
Button sqlButton;
SQL data = new SQL();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sqlButton = (Button) findViewById(R.id.sqlButton);
sqlButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
data.getData();
}
});
}
}
You would have to write a webservice to connect to any external databases such as MYSQL to connect android application to a database. It also involves writing a very basic PHP script.
See the following link for some examples.
https://www.b4x.com/android/forum/threads/connect-android-to-mysql-database-tutorial.8339/
http://www.androidhive.info/2012/05/how-to-connect-android-with-php-mysql/
So you're better off using SQLLite unless its absolutely necessary.
Related
package com.example.workdb;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.StrictMode;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.os.Bundle;
import android.widget.TextView;
import org.w3c.dom.Text;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import net.sourceforge.jtds.jdbc.*;
public class MainActivity extends AppCompatActivity {
public Button run;
public TextView message;
public TextView txtvw;
public Connection con;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
run= (Button) findViewById(R.id.button);
run.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
CheckLogin checkLogin= new CheckLogin();
checkLogin.execute("");
Log.d("CREATION","ON CREATE WORKS");
// Log.d("txtvw", connection);
//System.out.println("Yes");
// txtvw.setText("hello");
}
});
} public class CheckLogin extends AsyncTask<String,String,String>
{
String z="";
Boolean IsSuccess= false;
String name1="";
// Log.d("txtvw","step 1 done");
protected void onPostExecute(String r){
if (IsSuccess){
message=(TextView)findViewById(R.id.textView);
message.setText(name1);
Log.d("TAG", "STEP 1 DONE");
}
}
#Override
protected String doInBackground(String... strings) {
try
{
Connection con = connectionClass();
if(con==null){
z="Check interent";
//Log.d("txtvw", z);
}
else
{
String query= "select * from Value";
Statement stmt= con.createStatement();
ResultSet rs= stmt.executeQuery(query);
if (rs.next())
{
name1=rs.getString("KneeAngle");
Log.d("MYTAG", "name 1 works");
z="Query success";
IsSuccess=true;
con.close();
}
else{
z="Invalid query";
IsSuccess=false;
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return z;
}
}
public Connection connectionClass(){
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Connection connection = null;
String ConnectionURL ;
try{
Class.forName("net.sourceforge.jtds.jdbs.Driver");
ConnectionURL="jdbc:jtds:sqlserver://havvasemserv3.database.windows.net:1433;DatbaseName=Newfin;user=;password=;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30";
connection= DriverManager.getConnection(ConnectionURL);
} catch(ClassNotFoundException e){
Log.e("Error here 2 ",e.getMessage());
}
catch (Exception e) {
Log.e("error here 3:",e.getMessage());
}
//Log.d("txtvw", connection);
return connection;
}
}
I am trying to connect azure sql database to android studio. I have added all the permissions in the manifest file and I have also added a jtds module 1.3.1 in the project and implemented it in the gradle module app. My code exits with 0 errors but data is not displayed on the emulator. Expected output is the first value from my database which is "8".
Thanks.,
Add this at the end of you current connection url after timeout=30
;ssl=request
Also make sure in your firewall settings of your azure server!/database your current device ip is allowed to access as by default all access is blocked,
To allow all devices to access server go to the firewall settings and in the insert ip section add this ip range
0,0,0,0 and 255,255,255,255
I tried to connect my android app to SQL DB using JDBC connector. If I try it in Netbeans, so it's OK and the connection is working. I am using connector: mssql-jdbc-8.2.2.jre13
package sql_server;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Sql_server {
public static void main(String[] args) {
String url = "jdbc:sqlserver://localhost\\MSSQLSERVER19;databaseName=Helios002";
String user = "user";
String password = "password";
String query = "select top 1 skupzbo, regcis, nazev1 from Tabkmenzbozi order by id desc";
try ( Connection con = DriverManager.getConnection(url, user, password); Statement st = con.createStatement(); ResultSet rs = st.executeQuery(query)) {
if (rs.next()) {
System.out.println(rs.getString(1) + rs.getString(2) + rs.getString(3));
}
} catch (SQLException ex) {
System.out.println("An error occurred while connecting MySQL databse");
ex.printStackTrace();
}
}
}
But in android studio it's not working.I am using connector:mssql-jdbc-8.2.2.jre11, because mssql-jdbc-8.2.2.jre13 is not supported by android studio.
package com.example.hepopr.ui.gallery;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import com.example.hepopr.R;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
public class GalleryFragment extends Fragment {
private TextView test;
public static String url = "jdbc:sqlserver://localhost\\MSSQLSERVER19;databaseName=Helios002";
public static final String user = "user";
public static final String pass = "password";
private GalleryViewModel galleryViewModel;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
galleryViewModel =
ViewModelProviders.of( this ).get( GalleryViewModel.class );
View root = inflater.inflate( R.layout.fragment_gallery, container, false );
final TextView textView = root.findViewById( R.id.text_gallery );
galleryViewModel.getText().observe( getViewLifecycleOwner(), new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
textView.setText( s );
}
} );
test=root.findViewById( R.id.textView2 );
return root;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
Timer timer = new Timer();
//Set the schedule function
timer.scheduleAtFixedRate( new TimerTask() {
#Override
public void run() {
new MyTask().execute();
}
},0, 30000 ); // 1000 Millisecond = 1 second
}
private class MyTask extends AsyncTask<Void, Void, Void> {
private String STvody = "", STvzduchu = "", SVlhkost = "", SCerpadlo = "", SHladina = "", SSvetlo = "", SDate = "", STlak = "";
#Override
protected Void doInBackground(Void... arg0) {
try {
Class.forName( "com.microsoft.sqlserver.jdbc.SQLServerDriver" );
Connection con = DriverManager.getConnection( url, user,pass);
if (con == null) {
Toast.makeText( getActivity(), "Nepřipojeno", Toast.LENGTH_SHORT ).show();
} else {
Statement st = con.createStatement();
String sql = "select top 1 regcis from Tabkmenzbozi order by id desc ";
final ResultSet rs = st.executeQuery( sql );
if (rs == null) {
Toast.makeText( getActivity(), "Bez dat", Toast.LENGTH_SHORT ).show();
}
Objects.requireNonNull( rs ).next();
SDate = rs.getString( 1 );
String pattern = "HH:mm:ss";
DateFormat df = new SimpleDateFormat(pattern);
Date today = Calendar.getInstance().getTime();
// todayAsString = df.format( today );
con.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
test.setText( SDate );
super.onPostExecute( result );
}
}
}
And studio returns an error:
W/System.err: com.microsoft.sqlserver.jdbc.SQLServerException: The connection to the host localhost, named instance mssqlserver19 failed. Error: "java.net.SocketTimeoutException: Poll timed out". Verify the server and instance names and check that no firewall is blocking UDP traffic to port 1434. For SQL Server 2005 or later, verify that the SQL Server Browser Service is running on the host.
W/System.err: at com.microsoft.sqlserver.jdbc.SQLServerConnection.getInstancePort(SQLServerConnection.java:6068)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.primaryPermissionCheck(SQLServerConnection.java:2457)
W/System.err: at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:2200)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:2067)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1204)
W/System.err: at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:825)
at java.sql.DriverManager.getConnection(DriverManager.java:569)
at java.sql.DriverManager.getConnection(DriverManager.java:219)
W/System.err: at com.example.hepopr.ui.gallery.GalleryFragment$MyTask.doInBackground(GalleryFragment.java:84)
at com.example.hepopr.ui.gallery.GalleryFragment$MyTask.doInBackground(GalleryFragment.java:76)
W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Can you help me, what wrong is?
Thank you.
Don't do this. Ever. Your db password is in your code, which is going out to devices. That means with 30 minutes of effort anyone can get your db password and screw with your data. You should only ever interact with a remote db through a webservice, so only the webservice (on your hardware) has the keys to your database. Anything else is incredibly insecure.
JDBC can be used server side securely because its only run on your server. But it should never be used on devices you don't physically control.
i have a big problem. My search with UserSearchManager is working fine but i dont understand how i put the results of the search in my list view.
The result type from the search is saved at a list and i wanna take the values from the row and put the result of the row in my list View in Android, but i dont get it, how i should start?
So i hope you can help me.
Moreover a have an another problem with the Iterator.
Android Studio say it cannot resolve the problem and a cast wont help me.
Iterator<Row> it = resultData.getRows();
Row row = it.next();
Iterator iterator = row.getValues("jid");
This lines are the problem. In many other threads, people have the same code snippets and theres working, but for me not.
Here is my complete code.
package de.hsrt.campusapp.app.module.xmppchat;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smackx.iqregister.packet.Registration;
import org.jivesoftware.smackx.search.ReportedData;
import org.jivesoftware.smackx.search.UserSearchManager;
import org.jivesoftware.smackx.xdata.Form;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import de.hsrt.campusapp.app.CampusAppConstants;
import de.hsrt.campusapp.app.R;
public class ActivitySearchContact extends AppCompatActivity {
private final static String serverDomain = "search.ewcexmpp1";
private static DomainBareJid serverDomainBareJid;
private ReportedData resultData;
private ListView contactList;
private EditText contactName;
private ImageButton searchContact;
private XMPPTCPConnection con = CampusAppConstants.xmppController.getNetworkManager().getXmppTCPConnection();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_contact);
contactList = (ListView) findViewById(R.id.listViewForSearchAnswer);
contactName = (EditText) findViewById(R.id.editTextContactInput);
searchContact = (ImageButton) findViewById(R.id.btn_searchContactDetail);
searchContact.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String strContact = contactName.getText().toString();
userSearch(strContact);
}
});
}
/**
* Diese Methode soll mir alle gesuchten Kontakte zurückliefern
*
* #return
*/
public ReportedData userSearch(String searchname) {
//hier eventuell die campusappconstants mit der verbindung benutzen
UserSearchManager userSearchManager = new UserSearchManager(con);
try {
Form searchForm = userSearchManager.getSearchForm(getServerDomainBareJid());
//erstellt die antwort form
Form answerForm = searchForm.createAnswerForm();
//die eigentliche suche, ich suche in der spalte Username
answerForm.setAnswer("Username", true);
answerForm.setAnswer("search", searchname);
//hier hol ich das ergebnis
this.resultData = userSearchManager.getSearchResults(answerForm, getServerDomainBareJid());
Toast.makeText(this, resultData.getRows().toString(), Toast.LENGTH_LONG).show();
if(resultData.getRows() != null)
{
Iterator<Row> it = resultData.getRows();
while(it.hasNext())
{
Row row = it.next();
Iterator iterator = row.getValues("jid");
if(iterator.hasNext())
{
String value = iterator.next().toString();
Log.i("Iteartor values......"," "+value);
}
//Log.i("Iteartor values......"," "+value);
}
Toast.makeText(this,"Username Exists",Toast.LENGTH_SHORT).show();
}
}catch(Exception e){
e.printStackTrace();
e.getMessage();
//Log.e(this.getClass().getSimpleName().toString(), "Fehler bei der Suche", e);
}
return this.resultData;
}
private static DomainBareJid getServerDomainBareJid() {
try {
serverDomainBareJid = JidCreate.domainBareFrom(serverDomain);
} catch (XmppStringprepException e) {
e.printStackTrace();
}
return serverDomainBareJid;
}
}
package com.efas.admin.efasrestaurant;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LoginPage extends AppCompatActivity {
EditText Username;
EditText Password;
Button button1;
Button button2;
Connection connect;
SimpleAdapter AD;
private Connection CONN(String _user , String _pass , String _DB , String _server){
StrictMode.ThreadPolicy policy= new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Connection Conn=null;
String connString;
try{
connect = CONN("sa", "123456789", "EFAS", "192.168.0.101");
Class.forName("net.sourceforge.jtds.jdbc.Driver");
connString = "jdbc:jtds:sqlserver://server_ip_address :192.168.0.101/EFAS;encrypt=fasle;user=sa;password=123456789;instance=BLAZE;";
Conn = DriverManager.getConnection(connString);
Log.w("Connection","open");
Statement stmt = connect.createStatement();
stmt.executeQuery("select * from UserName");
Statement stmt1 = Conn.createStatement();
stmt1.executeQuery("select * from UserPassword");
}catch (SQLException se){
Log.e("ERROR",se.getMessage());
}catch (ClassNotFoundException e){
Log.e("ERROR",e.getMessage());
}catch (Exception e){
Log.e("ERROR",e.getMessage());
}
return CONN(_user, _pass, _DB, _server);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_page);
Username=(EditText)findViewById(R.id.edit_text1);
Password=(EditText)findViewById(R.id.edit_text2);
button1=(Button)findViewById(R.id.btn1);
button2=(Button)findViewById(R.id.btn2);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Username.getText().toString().equals("stmt")&&
Password.getText().toString().equals("stmt1")) {
Toast.makeText(LoginPage.this, "Username and Password is correct", Toast.LENGTH_SHORT).show();
EditText editText = (EditText) findViewById(R.id.edit_text1);
Intent i = new Intent(getApplicationContext(), TableLists.class);
i.putExtra("text", editText.getText().toString());
startActivity(i);
} else
{Toast.makeText(LoginPage.this,"Please Enter a Valid Username and Password ",Toast.LENGTH_SHORT).show();
Toast.makeText(LoginPage.this,"And Try Again",Toast.LENGTH_SHORT).show();
}
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i=new Intent(getApplicationContext(),EFAS.class);
startActivity(i);
}
});
public String getMacAddress(Context context){
WifiManager wifiManager=(WifiManager)context.getSystemService(Context.WIFI_SERVICE);
String macAddress = wifiManager.getConnectionInfo().getMacAddress();
if (macAddress == null) {
macAddress = "Device don't have mac address or wi-fi is disabled";
}
return macAddress;
}
}
when i enter username as stmt and password as stmt1 then the next activity starts but it is supposed to take username and password input from the database
and it is not happining when i enter the username and password of the database it goes to else condition how can i fix this ???
try
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskWrites().penaltyLog().build());
I tried to implement a simple publisher and subscriber in android using zeromq. When i try to debug it loops in subscriber recv. I dont know where i am going wrong. I think it is not able to get any data from the publisher.
Below is the code :subscriber
package com.example.jeromqps;
import java.util.*;
import org.jeromq.ZMQ;
import android.os.AsyncTask;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
public class client implements Runnable {
Messenger messenger;
public client()
{
System.out.println("client started");
}
#Override
public void run()
{
ZMQ.Context context=ZMQ.context(1);
System.out.println("collecting data from server");
ZMQ.Socket subscriber=context.socket(ZMQ.SUB);
subscriber.connect("tcp://localhost:4444");
String code="10001";
subscriber.subscribe(code.getBytes());
int totalvalue=0;
//store the data in a data structure
for(int i=0;i<10;i++)
{
byte[] msg = subscriber.recv(0);
String string=new String(subscriber.recv(0));
StringTokenizer sscanf=new StringTokenizer(string," ");
int value=Integer.valueOf(sscanf.nextToken());
String string= new String(msg);
System.out.println();
totalvalue+=value;
}
int avg=totalvalue;
Message msg1=Message.obtain();
msg1.obj=string;
try {
messenger.send(msg1);
System.out.println("sent to main");
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
subscriber.close();
context.term();
}
}
The publisher code is below
package com.example.jeromqps;
import java.util.*;
import org.jeromq.*;
public class server implements Runnable{
public server()
{
System.out.println("server started");
}
#Override
public void run()
{
ZMQ.Context context=ZMQ.context(1);
ZMQ.Socket publisher=context.socket(ZMQ.PUB);
publisher.bind("tcp://*:4444");
Random srandom=new Random(System.currentTimeMillis());
System.out.println("in server");
while(!Thread.currentThread().isInterrupted())
{ //System.out.println("in while")
int zipcode =1000 +srandom.nextInt(10000);
int temperature = srandom.nextInt(215) - 80 + 1;
String update = String.format("%05d %d", zipcode, temperature);
String update="publisher";
publisher.send(update.getBytes(),0);
}
publisher.close();
context.term();
}
}
Main is below:
package com.example.jeromqps;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.os.Handler;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends Activity implements Handler.Callback {
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new server()).start();
new Thread(new client()).start();
}
#Override
public boolean handleMessage(Message arg0)
{
String str = new String((byte[]) arg0.obj);
System.out.println("****");
System.out.println(str);
//new AlertDialog.Builder(this).setMessage(str).show();
System.out.println("****");
textView.append(str+ "\n");
return false;
}
}
In program loops at byte[] msg = subscriber.recv(0); in the subscribers class. Where am i going wrong?Am i missing something?
First of all, you've got some errors in the code:
In the publisher, update is defined twice
String update = String.format("%05d %d", zipcode, temperature);
String update= "publisher";
You have a similar problem in the subscriber code, string is defined twice...
String string = new String(subscriber.recv(0));
String string = new String(msg);
In the subscriber, you're receiving messages twice in the same iteration..
byte[] msg = subscriber.recv(0);
String string = new String(subscriber.recv(0));
...you only need this in the loop to receive...
String string = new String(subscriber.recv(0));
Try fixing those problems and see how far you get...
This isn't a solution to the question posted here, but reading this question I noticed that 0 was specified as the second parameter in the send(...) method, which subsequently matches the parameter set in the recv(...) method.
I have a simple pub/sub system set up and couldn't figure out why messages weren't being sent. I was using recv(0) but was specifying some random flag in the send(...) method. Changing the value to 0 fixed my issues.
Figured I'd post this here as it was from reading through the code in the question that I happened to have that thought. So maybe this will help someone else in the future.