I am reading JAVAX response using readEntity() method but I am getting following stacktrace :
java.lang.IllegalStateException: Entity input stream has already been closed.
at org.glassfish.jersey.message.internal.EntityInputStream.ensureNotClosed(EntityInputStream.java:225) ~[jersey-common.jar:?]
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:832) ~[jersey-common.jar:?]
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:785) ~[jersey-common.jar:?]
at the line
Map<String, Map> mapEntityFromResponse = res.readEntity(Map.class);
Here is my code
public Output getClaimsFromAPI(#NonNull final Input xyzInput)
throws PermanentException, TransientException {
final Response res = fetchHealBeamServiceResponse(webTarget, xyzInput);
Object respondentMapObject;
Map<String, Map> mapEntityFromResponse = res.readEntity(Map.class);
if (mapEntityFromResponse != null) {
respondentMapObject = mapEntityFromResponse.get(ServiceConstants.MAP_KEY);
return getOutputFromResponseMap(respondentMapObject, xyzInput);
} else {
throw new RuntimeException("The response returned does not contain map");
}
}
private Response fetchHealBeamServiceResponse(WebTarget healBeamTarget,
Input xyzInput)
throws PermanentException, TransientException {
Response res = null;
try {
res = healBeamTarget
.path(HealBeamServiceConstants.GET_CUSTOMER_PATH)
.register(Configurator.getSoaOpNameFeatureForCustomerResource())
.resolveTemplate(ServiceConstants.ID, xyzInput.getId())
.request(MediaType.APPLICATION_JSON_TYPE)
.property(HealBeamServiceConstants.SERVICE_KEY, SOA_SERVICE_NAME)
.property(HealBeamServiceConstants.OPERATION_KEY, SOA_OP_NAME_GET_CUSTOMER)
.acceptLanguage(java.util.Locale.getDefault())
.get();
if (Response.Status.REQUEST_TIMEOUT.getStatusCode() == res.getStatusInfo().getStatusCode()) {
throw new TransientException("Request timed out with status" + res.getStatusInfo().getStatusCode());
} else if (Response.Status.OK.getStatusCode() != res.getStatusInfo().getStatusCode()) {
log.error("Some Error"):
}
return res;
} catch (RuntimeException e) {
throw new PermanentException("Unexpected Exception Occured, Exception Message " + e.getMessage());
} finally {
if (res != null) {
res.close();
}
}
}
You are closing your response in finally right before it gets returned, that is the reason, why you can't read from it in your calling method getClaimsFromAPI().
Just to demonstrate: What do you think the method main() posted below would print?
public class NewApp {
public static void main(String[] args) {
Person p = demonstrate();
System.out.println(p.name);
}
public static Person demonstrate(){
Person person = new Person();
try {
person.name = "name set in try";
return person;
} catch (Exception ex) {
throw ex;
} finally {
person.name = "name set in finally";
}
}
}
class Person {
public String name;
}
I would to display data from an arrayList into a TableView but I have some problem with the mechanism of ''setCellValueFactory''.
The code is this:
public class Example implements Comparable<Example>{
private List<Object> example=new ArrayList<Object>();
public void add(Object o){
example.add(o);
}
public Object get(int i){
return example.get(i);
}
public int compareTo(Example ex) {
int i=0;
for(Object o:ex.example){
if(!o.equals(this.example.get(i)))
return ((Comparable)o).compareTo(example.get(i));
i++;
}
return 0;
}
public String toString(){
String str="";
for(Object o:example)
str+=o.toString()+ " ";
return str;
}
}
public void start(Stage stage) throws SQLException, DatabaseConnectionException {
....
....
....
....
....
....
tab.setMinWidth(700);
tables.getSelectionModel().selectedItemProperty().addListener(
(ov,old_val,new_val)->{
tab.getColumns().clear();
try {
List<Example> data = new ArrayList<Example>();
TableData tableData = new TableData(new DbAccess((String)dataBases.getValue()));
data = tableData.getDistinctTransazioni(new_val);
TableSchema tableSchema = new TableSchema(new DbAccess((String)dataBases.getValue()),new_val);
for (int i=0;i<tableSchema.getNumberOfAttributes();i++) {
TableColumn column = new TableColumn(tableSchema.getColumn(i).getColumnName());
tab.getColumns().add(column);
}
ObservableList<Example> values = FXCollections.
observableArrayList(data);
tab.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
tab.setItems(values);
} catch (SQLException e1) {
e1.printStackTrace();
} catch (DatabaseConnectionException e1) {
e1.printStackTrace();
} catch (EmptySetException e1) {
e1.printStackTrace();
}
}
);
In the method : column.setCellValueFactory(new PropertyValueFactory<>("Here what I put?")).- I don't have a property but I have an arrayList of Object in class Example.
I been trying to develop a Minecraft server plugin where a player enters a command with some data, data is sent to database, or, a command that requests some data from database.
It's working, until a user starts using it more then a few times. I get a leakdetection error:
[HikariPool-2 housekeeper] WARN com.zaxxer.hikari.pool.ProxyLeakTask - Connection leak detection triggered for com.mysql.jdbc.JDBC4Connection#abc6eb, stack trace follows
[23:36:11 WARN]: java.lang.Exception: Apparent connection leak detected
Or I get an error that tells me that I have too many connections. (Sorry, I don't have that error at this moment)
This is the gist of my code. What am I doing improperly?
public class MochaModel {
private Latte instance = Latte.getInstance();
private Connection connection;
public MochaModel() {
}
public void createTable() {
BukkitRunnable r = new BukkitRunnable() {
#Override
public void run() {
try {
connection = Database.getConnection();
if (connection != null) {
String sql = "CREATE TABLE IF NOT EXISTS `mocha` ( " +
" `id` INT NOT NULL AUTO_INCREMENT ," +
"`uuid` VARCHAR(255) NOT NULL ," +
" `join_message` VARCHAR(255) NOT NULL ," +
" `quit_message` VARCHAR(255) NOT NULL ," +
" `change_points` INT NOT NULL," +
" `last_modified` TIMESTAMP NOT NULL," +
" PRIMARY KEY (`id`)" +
")";
PreparedStatement q = connection.prepareStatement(sql);
q.executeUpdate();
}
} catch(SQLException e) {
e.printStackTrace();
} finally {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
};
r.runTaskAsynchronously(instance);
}
public void setJoinMessage(String uuid, String message) {
ResultSet rs = getDataWithUUID(uuid);
String[] sqlValues = new String[2];
try {
if (!rs.isBeforeFirst()) {
String insertSql = "INSERT INTO `mocha` (`uuid`, `join_message`,`quit_message`, `change_points`, `last_modified`) VALUES (?, ?, '', 0, CURRENT_TIMESTAMP)";
sqlValues[0] = uuid;
sqlValues[1] = message;
insertData(insertSql, sqlValues);
} else {
while (rs.next()) {
String updateSql = "UPDATE `mocha` SET `join_message`=? WHERE `uuid`=?";
sqlValues[0] = message;
sqlValues[1] = uuid;
updateData(updateSql, sqlValues);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public void setQuitMessage(String uuid, String message) {
ResultSet rs = getDataWithUUID(uuid);
String[] sqlValues = new String[2];
try {
if (!rs.isBeforeFirst()) {
String insertSql = "INSERT INTO `mocha` (`uuid`, `join_message`,`quit_message`, `change_points`, `last_modified`) VALUES (?, '', ?, 0, CURRENT_TIMESTAMP)";
sqlValues[0] = uuid;
sqlValues[1] = message;
insertData(insertSql, sqlValues);
} else {
while (rs.next()) {
String updateSql = "UPDATE `mocha` SET `quit_message`=? WHERE `uuid`=?";
sqlValues[0] = message;
sqlValues[1] = uuid;
updateData(updateSql, sqlValues);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
private void updateData(String sql, String[] sqlValues) {
BukkitRunnable r = new BukkitRunnable() {
#Override
public void run() {
try {
connection = Database.getConnection();
if (connection != null) {
PreparedStatement q = connection.prepareStatement(sql);
q.setString(1, sqlValues[0]);
q.setString(2, sqlValues[1]);
System.out.println(q);
q.executeUpdate();
}
} catch(SQLException e) {
e.printStackTrace();
} finally {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
};
r.runTaskAsynchronously(instance);
}
private void updateChangePointsData(String sql, String[] sqlValues) {
BukkitRunnable r = new BukkitRunnable() {
#Override
public void run() {
try {
connection = Database.getConnection();
if (connection != null) {
PreparedStatement q = connection.prepareStatement(sql);
q.setInt(1, Integer.parseInt(sqlValues[0]));
q.setString(2, sqlValues[1]);
System.out.println(q);
q.executeUpdate();
}
} catch(SQLException e) {
e.printStackTrace();
} finally {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
};
r.runTaskAsynchronously(instance);
}
private void insertData(String sql, String[] sqlValues) {
BukkitRunnable r = new BukkitRunnable() {
#Override
public void run() {
try {
connection = Database.getConnection();
if (connection != null) {
PreparedStatement q = connection.prepareStatement(sql);
q.setString(1, sqlValues[0]);
q.setString(2, sqlValues[1]);
System.out.println(q);
q.executeUpdate();
}
} catch(SQLException e) {
e.printStackTrace();
} finally {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
};
r.runTaskAsynchronously(instance);
}
private ResultSet getDataWithUUID(String uuid) {
ResultSet result = null;
String sqlPlayer = "SELECT * FROM `mocha` WHERE `uuid` = ?";
try {
connection = Database.getConnection();
if (connection != null) {
PreparedStatement q = connection.prepareStatement(sqlPlayer);
q.setString(1, uuid);
result = q.executeQuery();
}
} catch(SQLException e) {
e.printStackTrace();
}
return result;
}
public String getMessage(String uuid, String messageType) {
ResultSet rs = getDataWithUUID(uuid);
String message = null;
try {
if (!rs.isBeforeFirst()) {
message = null;
} else {
while (rs.next()) {
if (messageType.equalsIgnoreCase("getjoin")) {
message = rs.getString("join_message");
} else if (messageType.equalsIgnoreCase("getquit")) {
message = rs.getString("quit_message");
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return message;
}
public int getChangePoints(String uuid) {
ResultSet rs = getDataWithUUID(uuid);
int changePoints = 0;
try {
if (!rs.isBeforeFirst()) {
changePoints = 0;
} else {
while (rs.next()) {
changePoints = rs.getInt("change_points");
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return changePoints;
}
public void removeChangePoints(String uuid, int amount) {
int changePoints = getChangePoints(uuid);
String[] sqlValues = new String[2];
if (changePoints >= amount) {
String updateSql = "UPDATE `mocha` SET `change_points`=? WHERE `uuid`=?";
sqlValues[0] = String.valueOf((changePoints-amount));
sqlValues[1] = uuid;
updateData(updateSql, sqlValues);
}
}
public void addChangePoints(String uuid, int amount) {
int changePoints = getChangePoints(uuid);
String[] sqlValues = new String[2];
String updateSql = "UPDATE `mocha` SET `change_points`=? WHERE `uuid`=?";
sqlValues[0] = String.valueOf((changePoints+amount));
sqlValues[1] = uuid;
updateChangePointsData(updateSql, sqlValues);
}
}
My DB Class:
public class Database {
private static Latte instance = Latte.getInstance();
private static Config config = new Config();
private static HikariConfig dbConfig;
static {
dbConfig = new HikariConfig();
dbConfig.setJdbcUrl("jdbc:mysql://localhost:3306/" + config.get("database.database"));
dbConfig.setUsername(config.get("database.username"));
dbConfig.setPassword(config.get("database.password"));
dbConfig.setDriverClassName("com.mysql.jdbc.Driver");
dbConfig.addDataSourceProperty("cachePrepStmts", "true");
dbConfig.addDataSourceProperty("prepStmtCacheSize", "250");
dbConfig.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
}
private static HikariDataSource ds = new HikariDataSource(dbConfig);
public static Connection getConnection() {
try {
ds.setIdleTimeout(60000);
ds.setConnectionTimeout(60000);
ds.setValidationTimeout(3000);
ds.setLoginTimeout(5);
ds.setMaxLifetime(60000);
ds.setMaximumPoolSize(20);
ds.setLeakDetectionThreshold(5000);
return ds.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
When opening a Connection you also need to close it. However you are storing the Connection in a instance variable. Which, for certain paths in your code, might result in multiple Connection instances being used. Due the the storage in the instance variable only the last one used will get closed, all the others are leaked.
Instead you want to make it local or hide parts of the complexity. You could rewrite your Database class to something like this.
Note: Assuming Java 8 here!
public class Database {
private static Latte instance = Latte.getInstance();
private static Config config = new Config();
private static HikariConfig dbConfig;
static {
dbConfig = new HikariConfig();
dbConfig.setJdbcUrl("jdbc:mysql://localhost:3306/" + config.get("database.database"));
dbConfig.setUsername(config.get("database.username"));
dbConfig.setPassword(config.get("database.password"));
dbConfig.setDriverClassName("com.mysql.jdbc.Driver");
dbConfig.addDataSourceProperty("cachePrepStmts", "true");
dbConfig.addDataSourceProperty("prepStmtCacheSize", "250");
dbConfig.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
}
private static HikariDataSource ds = new HikariDataSource(dbConfig);
public static <T> T execute(ConnectionCallback<T> callback) {
try (Connection conn = ds.getConnection()) {
return callback.doInConnection(conn);
} catch (SQLException e) {
throw new IllegalStateException("Error during execution.", e);
}
}
public static interface ConnectionCallback<T> {
public T doInConnection(Connection conn) throws SQLException;
}
}
Notice no more getConnection and due to the try-with-resources the connection will get closed automatically.
You can now call this method with instances of ConnectionCallback instead of getting the Connection and manage it yourself.
Now the code that uses the Connection can be refactored, to something like this. (Notice no more catches, closes etc. all that is handled in the Database.execute method.
private void updateData(String sql, String[] sqlValues) {
BukkitRunnable r = new BukkitRunnable() {
#Override
public void run() {
Database.execute( (conn) -> {
PreparedStatement q = conn.prepareStatement(sql);
q.setString(1, sqlValues[0]);
q.setString(2, sqlValues[1]);
System.out.println(q);
q.executeUpdate();
return null;
}} );
};
r.runTaskAsynchronously(instance);
}
This code will close the Connection after each use (and you cannot forget to close it).
I wrote a program which connects to a MQTT Broker and stores every MQTT message to a Mongo database. It works fine but I'm really not sure I've done it the right way. It opens lots of connections to the mongo server.
Here is the code :
public class MqttConnection {
private static final String BROKER_IP = Preferences.getProperty("mqttbroker-ip");
private static final String BROKER_PORT = Preferences.getProperty("mqttbroker-port");
private static final String BROKER_URI = "tcp://" + BROKER_IP + ":" + BROKER_PORT;
private static final String CLIENT_ID = Preferences.getProperty("mqttbroker-clientid");
private static final String USERNAME = Preferences.getProperty("mqttbroker-username");
private static final String PASSWORD = Preferences.getProperty("mqttbroker-password");
private static final String TOPIC = Preferences.getProperty("mqttbroker-topic");
private static final SimpleDateFormat SDF = new SimpleDateFormat("YYYYMMddHH:mm:ss");
private static MqttClient client;
private static final MqttConnectOptions options;
private static final MongoClient mongoClient;
public enum Type {
Double, Boolean, String;
}
static {
mongoClient = MongoConnection.getInstance();
try {
client = new MqttClient(BROKER_URI, CLIENT_ID);
} catch (MqttException ex) {
Logger.getLogger(MqttConnection.class.getName()).log(Level.SEVERE, null, ex);
}
options = new MqttConnectOptions();
options.setUserName(USERNAME);
options.setPassword(PASSWORD.toCharArray());
}
public static void connect() {
try {
if (Preferences.getProperty("mqttbroker-isAuth").equalsIgnoreCase("true")) {
client.connect(options);
} else {
client.connect();
}
System.out.println(SDF.format(new Date()) + " - MQTT - Connecté au broker");
client.setCallback(new ConnectionCallback());
client.subscribe(TOPIC);
} catch (MqttException ex) {
System.out.println(SDF.format(new Date()) + " - MQTT - Erreur de connexion... Nouvelle tentative dans 5 secondes...");
if (!client.isConnected()) {
try {
Thread.sleep(5000);
} catch (InterruptedException ex1) {
Logger.getLogger(MqttConnection.class.getName()).log(Level.SEVERE, null, ex1);
}
connect();
}
}
}
static class ConnectionCallback implements MqttCallback {
#Override
public void connectionLost(Throwable thrwbl) {
System.out.println(SDF.format(new Date()) + " - MQTT - Perte de connexion... Tentative de reconnexion...");
connect();
}
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
new Thread(new Runnable() {
#Override
public void run() {
String[] tab = topic.split("/", 2);
String dbName = tab[0];
String collName = (tab.length > 1) ? tab[1] : tab[0];
MongoDatabase db = mongoClient.getDatabase(dbName);
MongoCollection collection = db.getCollection(collName);
Document doc = (Document) collection.find().sort(Sorts.descending("date")).first();
Object value = (doc != null) ? doc.get("value") : null;
Type type = checkType(message.toString());
switch (type) {
case Double :
if (doc == null || !((Double) value).equals(Double.valueOf(message.toString()))) {
collection.insertOne(new Document()
.append("date", SDF.format(new Date()))
.append("value", Double.valueOf(message.toString())));
}
break;
case Boolean :
if (doc == null || !((Boolean) value).equals(Boolean.valueOf(message.toString()))) {
collection.insertOne(new Document()
.append("date", SDF.format(new Date()))
.append("value", Boolean.valueOf(message.toString())));
}
break;
case String :
if (doc == null || !((String) value).equals(message.toString())) {
collection.insertOne(new Document()
.append("date", SDF.format(new Date()))
.append("value", message.toString()));
}
break;
}
}
private Type checkType(String str) {
if (str.equalsIgnoreCase("true") || str.equalsIgnoreCase("false"))
return Type.Boolean;
else {
try {
Double.valueOf(str);
return Type.Double;
} catch (NumberFormatException e) {
return Type.String;
}
}
}
}).start();
}
#Override
public void deliveryComplete(IMqttDeliveryToken imdt) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
Thanks
public class Model
{
public static Connection getConnection()
{
Connection conn = null;
try
{
Class.forName("oracle.jdbc.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe", "System", "system");
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
catch(SQLException e)
{
e.printStackTrace();
}
return conn;
}
public static class Cart
{
public String itmName="";
public int howmany=0;
public static long itmQty=0, itmID=0;
public double itmPrice=0.0, itmCost=0.0, totalSum=0.0;
}
public static ArrayList<Cart> getCartDatabase(String user) throws Exception
{
Connection conn = getConnection();
String sql = "select * from userCarts where userID = '" + user + "'";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rst = pstmt.executeQuery();
ArrayList<Cart> al = null;
Cart crt=null;
while(rst.next())
{
System.out.println("CPoint");
try
{
long p = rst.getLong("itemID");
crt.itmID = p; // This is the line thats creating the error
System.out.println(p + " is long! I guess...");
}
catch(NullPointerException e)
{
System.out.println("NPE Caught in Model");
}
System.out.println("CP 1 " + crt.itmID);
ArrayList<row> alr=null;
try
{
alr = Model.getStoreInventory();
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("CP 2");
for(int i=0; i<alr.size(); i++)
{
crt.itmName = alr.get(i).itmName;
crt.itmPrice = alr.get(i).itmPrice;
crt.itmQty = alr.get(i).itmQty;
}
System.out.println("CP 3");
crt.howmany = rst.getInt("howmany");
crt.itmCost = crt.itmPrice*crt.howmany;
al.add(crt);
}
return al;
}
}
When I try to access this method of getCartFromDatabase, it gives a NullPointerException however I don't understand why it would do this. Moreover, I tried to make the class as a non static class too, but still it gave the same error:
"Possible deferencing Null Pointer"
Cart crt=null;
while(rst.next())
{
System.out.println("CPoint");
try
{
long p = rst.getLong("itemID");
crt.itmID = p; // This is the line thats creating the error
System.out.println(p + " is long! I guess...");
}
crt is null when you try to access crt.itemID. You have to assign it an instance first.
I think you may simply change the first line from the snippet to
Cart crt = new Cart();