I'm having a hard time trying to make the connection from my ireport with the system. My problem is that the system that I use is integrated, in other words, several of my clients will use the same system and therefore the same report. Here is the problem, the name of the bank and the ip of each client are not going to be the same everytime. So I would like to know how jasper could get the bank ip and the bank name from the system by itself and not by the connection made by ireport? Is there anyway to send these data to ireport by code? If so, how could I do that?
Here is a list of the data source and connection types provided by iReport:
-JDBC connection.
-JavaBean collection data source.
-XML data source.
-CSV data source.
-Hibernate connection.
-Spring-loaded Hibernate connection.
-Hadoop Hive data source.
-JRDataSourceProvider.
-Custom data source.
-Mondrian OLAP connection.
-XMLA connection.
-EJBQL connection.
-Empty data source.
for your case you need "JavaBean collection data source" to fill the report from your java code, using this two classes : net.sf.jasperreports.engine.data.JRBeanCollectionDataSource, net.sf.jasperreports.engine.data.JRBeanArrayDataSource
My system communicates through the class Connection. Java is possible to .jasper communicate with the database through this class?
My Connection
==============
package newpackage;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
/**
*
* #author User
*/
public class ConnectionJava {
Connection conn;
public Connection conectar() {
try {
Class.forName(DriverConnectionJava);
conn = DriverManager.getConnection(database, username, password);
} catch (SQLException ex) {
Logger.getLogger(ConnectionJava.class.getName()).log(Level.SEVERE, null, ex);
JOptionPane.showMessageDialog(null, "Error login with data base", "ERROR!", JOptionPane.ERROR_MESSAGE);
} catch (ClassNotFoundException ex) {
Logger.getLogger(ConnectionJava.class.getName()).log(Level.SEVERE, null, ex);
JOptionPane.showMessageDialog(null, "Error connection data base", "ERROR!", JOptionPane.ERROR_MESSAGE);
}
return conn;
}
public void desconect() {
try {
conn.close();
} catch (SQLException ex) {
Logger.getLogger(ConnectionJava.class.getName()).log(Level.SEVERE, null, ex);
}
}
private String database = "jdbc:mysql://localhost/Java";
private String username = "root";
private String password = "root";
private String DriverConnectionJava = "com.mysql.jdbc.Driver";
}
Related
Use case: As a user of the Spring AMQP client connecting to RabbitMQ brokers over TLS, I want to verify that the hostname(s) either in the X.509 certificate Common Name field or in one of the Subject Alternative Names in the certificate X.509 extensions matches the hostname I used to connect to the broker.
One possible solution: The Spring Rabbit connection factory bean org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean has a setSocketConfigurator(com.rabbitmq.client.SocketConfigurator) method on it that can be used configure the SSLSocket with a javax.net.ssl.HandshakeCompletedListener as follows in this simple SocketConfigurator
static class MySocketConfigurator implements SocketConfigurator {
private final String[] validHostnames;
public MySocketConfigurator(String[] validHostnames) {
this.validHostnames = validHostnames;
}
#Override
public void configure(final Socket socket) throws IOException {
if (socket instanceof SSLSocket) {
SSLSocket sslSocket = (SSLSocket) socket;
sslSocket.addHandshakeCompletedListener(new HandshakeCompletedListener() {
#Override
public void handshakeCompleted(final HandshakeCompletedEvent event) {
try {
if (event.getPeerCertificates()[0] instanceof X509Certificate) {
X509Certificate x509Certificate = (X509Certificate) event.getPeerCertificates()[0];
boolean verified = verifyHost(validHostnames, x509Certificate);
if (!verified) {
event.getSocket().close();
}
} else {
event.getSocket().close();
}
} catch (SSLPeerUnverifiedException e) {
throw new RuntimeException(e);
} catch (CertificateParsingException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
}
}
// verify that one of the validHostname items matches a host found in the broker certificate
boolean verifyHost(String[] validHostnames, X509Certificate serverCertificate) throws CertificateParsingException {
...
}
}
Closing the socket referenced in event.getSocket().close() seems a bit heavy-handed, but does suffice to shut the connection down if the application deems the hostnames in the certificate are not a close enough match. I had originally conceived to throw a RuntimeException upon determining that the hostnames did not match, but it appears the Spring stack swallows those and does not induce the desired application-induced connection setup failure.
Is the SocketConfigurator approach shown above, with its direct call to socket.close(), the recommended way to fail TLS connection setup if the certificate hostnames are deemed an insufficient match?
I am not sure what you mean by "spring stack swallows the exception"; doesn't sound right; if you can point me to the code that does that I can take a look.
The spring connection factory just delegates to the rabbit connection factory.
I don't know the answer to your basic question about best practices; you might want to ping the rabbit guys on the rabbitmq-users google group.
I am trying to authenticate user using JNDI, security level as SASL. Following is my sample code.
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
public class Test {
private static final String CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
private static final String PROVIDER_URL = "ldap://localhost:10389";
private static final String SECURITY_AUTHENTICATION = "DIGEST-MD5";
public static void main(String[] args) throws NamingException {
Hashtable<String, String> env = new Hashtable<String, String>(11);
env.put(Context.INITIAL_CONTEXT_FACTORY, CONTEXT_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
env.put(Context.SECURITY_AUTHENTICATION, SECURITY_AUTHENTICATION);
env.put(Context.SECURITY_PRINCIPAL,
"cn=Krishna,ou=people,dc=example,dc=com");
env.put(Context.SECURITY_CREDENTIALS, "password123");
try {
DirContext ctx = new InitialDirContext(env);
System.out.println("Authentication Successful");
ctx.close();
} catch (NamingException e) {
System.out.println("Authentication Failed");
e.printStackTrace();
}
}
}
I encrypted the password using MD5 algorithm in directory. When I tried to run above program, I am getting following error.
Authentication Failed
javax.naming.AuthenticationException: [LDAP: error code 49 - INVALID_CREDENTIALS: DIGEST-MD5: digest response format violation. Mismatched URI: ldap/localhost; expecting: ldap/ldap.example.com]
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3135)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3081)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2883)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2797)
at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:319)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.init(InitialContext.java:244)
at javax.naming.InitialContext.<init>(InitialContext.java:216)
at javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
at jndi_tutorial.Test.main(Test.java:26)
But when i tried to authenticate using simple mechanism (SECURITY_AUTHENTICATION = "simple"), My authentication is success. Is there any configurations I am missing?
Check if your LDAP server supports DIGEST-MD5 SASL mechanism.
DirContext ctx = new InitialDirContext();
Attributes attrs = ctx.getAttributes("ldap://<HSOT>:<PORT>", new String[]{"supportedSASLMechanisms"});
Check if the passwords are in fact stored as MD5 digest/hash in the LDAP server.
Connect to the LDAP sever with an LDPAP browser like Apache Dir Studio and check the password attribute. It will be prefixed with hash mechanism used.
I have currently doing Sentiment Analysis on Twitter data in Hadoop.
I have configured FLUME to bring data based upon certain keywords, which I have maintained in "FLUME.conf" file, as shown below
TwitterAgent.sources.Twitter.keywords = Kitkat, Nescafe, Carnation, Milo, Cerelac
With mentioning this, I would like to know whether it is possible to dynamically change the keywords, based upon a java program that will pop-up asking for keywords from user.
Also, apart from this method, please provide any other methods you folks would suggest to hide this complexity of updating the Flume.conf file.
Best Regards,
Ram
Flume provides an Application class to run its configuration file using a Java program.
public class Flume{
public static void main(String[] args) throws Exception
{
new Conf().setConfiguration();
String[] args1 = new String[] { "agent","-nTwitterAgent",
"-fflume.conf" };
BasicConfigurator.configure();
Application.main(args1);
System.setProperty("hadoop.home.dir", "/");
}
}
Here you will get a change to edit your conf file using some file utils like this
class Conf{
int ch;
String keyword ="";
Scanner sc= new Scanner(System.in);
public void setConfiguration(){
System.out.println("Enter the keyword");
keyword=sc.nextLine();
byte[] key= keyword.getBytes();
FileOutputStream fp=null;
FileInputStream src=null;
try{
fp= new FileOutputStream("flumee.conf");
src= new FileInputStream("flume.conf");
while((ch=src.read())!=-1){
fp.write((char)ch);
}
fp.write(key);
}catch(Exception e){
System.out.println("file Exception:"+ e);
}finally{
try{
if(fp!=null){
fp.close();
}
if(src!=null){
src.close();
}
}catch(Exception e){
System.out.println("file closing Exception:"+ e);
}
}
}
}
Now you need to keep the TwitterAgent.sources.Twitter.keywords= line at the end of your flume configuration file so that it will be easier for you to add the keywords into the file. My flume.conf file looks like this
TwitterAgent.sources= Twitter
TwitterAgent.channels= MemChannel
TwitterAgent.sinks=HDFS
TwitterAgent.sources.Twitter.type = com.cloudera.flume.source.TwitterSource
TwitterAgent.sources.Twitter.channels=MemChannel
TwitterAgent.sources.Twitter.consumerKey=xxx
TwitterAgent.sources.Twitter.consumerSecret=xxx
TwitterAgent.sources.Twitter.accessToken=xxx
TwitterAgent.sources.Twitter.accessTokenSecret=
TwitterAgent.sinks.HDFS.channel=MemChannel
TwitterAgent.sinks.HDFS.type=hdfs
TwitterAgent.sinks.HDFS.hdfs.path=hdfs://localhost:9000/user/flume/direct
TwitterAgent.sinks.HDFS.hdfs.fileType=DataStream
TwitterAgent.sinks.HDFS.hdfs.writeformat=Text
TwitterAgent.sinks.HDFS.hdfs.batchSize=1000
TwitterAgent.sinks.HDFS.hdfs.rollSize=0
TwitterAgent.sinks.HDFS.hdfs.rollCount=10000
TwitterAgent.sinks.HDFS.hdfs.rollInterval=600
TwitterAgent.channels.MemChannel.type=memory
TwitterAgent.channels.MemChannel.capacity=10000
TwitterAgent.channels.MemChannel.transactionCapacity=1000
TwitterAgent.sources.Twitter.keywords=
When i run the program it will ask for the keywords first and then it will start collecting the tweets about that keyword.
I used JNDI connection in my application and it is working. But I need to write Junits to test the connection. We dont use any spring framework. This is the method i wrote to get JNDI connection.
public Connection getConnection() throws SQLException {
DataSource ds = null;
InitialContext ic = null;
Connection con = null;
try {
ic = new InitialContext();
ds = (DataSource) ic.lookup("java:/DBs");
con = ds.getConnection();
return con;
} catch (Exception e) {
throw new SQLException(e);
}
}
You can make use of the SimpleNamingContextBuilder that comes with the spring-test library. You can use this even if you aren't using Spring as it isn't Spring specific.
Below is an example of setting up a JNDI connection in the #Before of the JUnit test.
package com.example;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.mock.jndi.SimpleNamingContextBuilder;
public class SomeTest
{
#Before
public void contextSetup () throws Exception
{
SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
DriverManagerDataSource dataSource = new DriverManagerDataSource("org.hsqldb.jdbcDriver", "jdbc:hsqldb:mem:testdb", "sa", "");
builder.bind("java:comp/env/jdbc/ds1", dataSource);
builder.bind("java:comp/env/jdbc/ds2", dataSource);
}
#Test
public void testSomething () throws Exception
{
/// test with JNDI
}
}
UPDATE: This solution also uses Spring's DriverManagerDataSource. If you want to use that you will also need the spring-jdbc library. But you don't have to use this, you can create any object you like and put it into the SimpleNamingContextBuilder. For example, a DBCP connection pool, a JavaMail Session, etc.
OK. After lot of searching i found a solution.And it is working for me. I want to share this to everybody. Hope this thing might help people who are having the same issue. Please add the below code.Add ojdb6.jar and naming-common-4.1.31.jar in your test libraries
#BeforeClass
public static void setUpClass() throws Exception {
try {
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES,"org.apache.naming");
InitialContext ic = new InitialContext();
ic.createSubcontext("java:");
ic.createSubcontext("java:/comp");
ic.createSubcontext("java:/comp/env");
ic.createSubcontext("java:/comp/env/jdbc");
OracleConnectionPoolDataSource ocpds = new OracleConnectionPoolDataSource();
ocpds.setURL("your URL");
ocpds.setUser("your username");
ocpds.setPassword("your password");
ic.bind("java:/yourJNDIName", ocpds);
} catch (NamingException ex) {
Logger.getLogger(yourTesTClass.class.getName()).log(Level.SEVERE, null, ex);
}
}
If this is running outside the app server, then you'll likely need to supply parameters to the call for the InitialContext. But also realize that many DataSource implementations are not serializable so they won't work outside the container.
What you're writing is an integration test and it should be run in the container.
Overview:
Our application extends a UIApplication and has a SMS Listener class that is registered on boot. When a message is received that fits our criteria we process the message and then we want to save it to a local SQLite database as well as upload it to a Web Server. It is important that this happens as soon as possible after the SMS is received, even if the UI Application is not open at that stage.
Problem:
When the SMSListener Instance is running in the background, with no UIApplication instance active, and wants to access the SQLite database or tries to create a HTTP Connection a “No Application Instance” exception is thrown.
Desired outcome:
We want to process, save and upload all the messages from the SMSListener background thread even if the UIApplication is not active. Currently the SMSListener background thread would store the messages in the RuntimeStore; when the UI Application is started it reads the messages from the RuntimeStore and saves it to the database. This is not an optimal solution though, because the synchronisation with the Web Server would also then only happen when the UI Application is next opened. It is important that it rather syncs when the message is received.
Application Pseudo Code:
Main Class, checks for startup and creates a SMSListener instance or gets the instance from the RuntimeStore.
public class OurAppUi extends UiApplication {
public static void main(String[] args) {
if (args != null && args.length > 0 && args[0].endsWith("gui")) {
// Create a new instance of the application and make the currently
// running thread the application's event dispatch thread.
OurAppUi theApp = new OurAppUi();
theApp.enterEventDispatcher();
} else {
// Entered through the alternate application entry point
SmsListener.waitForSingleton();
}
}
}
The SMSListener Class listens for any incoming messages, makes use of the RuntimeStore Singleton Model. This is working as expected.
public class SmsListener implements javax.wireless.messaging.MessageListener {
public static SmsListener waitForSingleton() {
//Ensure this is a singleton instance.
//Open RuntimeStore and obtain the reference of BackgroundListener
RuntimeStore store = RuntimeStore.getRuntimeStore();
Object obj = store.get(ID_BACKGROUND_LISTENER);
//If obj is null, there is no current reference to BackgroundListener
//Start a new instance of BackgroundLIstener if one is not running
if(obj == null) {
store.put(ID_BACKGROUND_LISTENER, new SmsListener());
return (SmsListener)store.get(ID_BACKGROUND_LISTENER);
} else {
return(SmsListener)obj;
}
}
public void notifyIncomingMessage(MessageConnection conn) {
new Thread() {
MessageConnection connection;
Thread set (MessageConnection con) {
this.connection = con;
return (this);
}
public void run() {
try {
Message m = connection.receive();
String msg = null;
if (m instanceof TextMessage) {
TextMessage tm = (TextMessage)m;
msg = tm.getPayloadText();
}
// Process the SMS
SMSObject sms = processSMS(msg);
// Save to DataBase { Exception is Thrown Here }
SQLManager.getInstance().save(sms);
// Upload to Web Server { Exception is Thrown Here }
WebServer.upload(sms);
} catch(Exception error) {
}
}
}.set(conn).start();
}
}
When the SmsListener Instance wants to access the SQLite database or tries to create a HTTP Connection a “No Application Instance” exception is thrown.
public final class SQLManager {
private SQLManager() {
try {
db = OpenOrCreateDatabase();
} catch (MalformedURIException e) {
Debug.log(TAG, "Get connection: URI: " + e.getMessage());
} catch (ControlledAccessException e) {
Debug.log(TAG, "Get connection: Controlled Access: " + e.getMessage());
} catch (DatabasePathException e) {
Debug.log(TAG, "Get connection: Database Path: " + e.getMessage());
} catch (DatabaseIOException e) {
Debug.log(TAG, "Get connection: Database IO: " + e.getMessage());
} catch (Exception e) {
Debug.log(TAG, e);
}
}
public static synchronized SQLManager getInstance() {
if (instance == null) {
instance = new SQLManager();
}
return instance;
}
}
We’ve tried store the SQLite instances in the RuntimeStore, using the same Singleton Model as the SMSListener but received errors when the UI Application tried to access the stored DB Instance.
In general the way to handle this type of activity is to divide the application into two parts:
The user interactive parts that need the UI and need only be run when the user wants to interact with the application;
The background processing part that will store the data and communicate with the remote server.
The background processing should take place under the context of an extension of a net.rim.device.api.system.Application which probably should be a RuntimeStore based singleton. This portion should be started from your auto run code, register the listeners and remain active. There are some complexities involved in making sure the code executes in the right context. I have a blog post which may be helpful.