I am testing out the atomikos transaction and database connectivity stuff, as a part of it i tried to execute the below code,
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import javax.sql.XAConnection;
import javax.transaction.Transaction;
import javax.transaction.xa.XAResource;
import com.atomikos.datasource.xa.jdbc.JdbcTransactionalResource;
import com.atomikos.icatch.config.UserTransactionServiceImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import com.atomikos.persistence.imp.StateRecoveryManagerImp;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
/**
* Working out how to use Atomikos, before building {#link Main}. It is not
* intended that you write your applications like this - use JCA+EJB or Spring
* instead! There is way too much boilerplate code here. Based on examples found
* at the Atomikos website.
*/
public class TestAtomikos {
public static void main(String[] args) throws Exception {
MysqlXADataSource mysql = new MysqlXADataSource();
mysql.setUser("root");
mysql.setPassword("root");
mysql.setUrl("jdbc:mysql://localhost:3306/world?useSSL=false");
JdbcTransactionalResource mysqlResource = new JdbcTransactionalResource(
"jdbc/mysql", mysql);
UserTransactionServiceImp utsi = new UserTransactionServiceImp();
utsi.registerResource(mysqlResource);
Properties prop = new Properties();
InputStream input = null;
//StateRecoveryManagerImp srmi = new StateRecoveryManagerImp(null);
try {
input = new FileInputStream("C:\\Users\\abcd\\eclipse\\workspace_Tomcat\\JNDI\\src\\main\\resources\\jta.properties");
// load a properties file
prop.load(input);
}
catch (IOException ex) {
ex.printStackTrace();
}
utsi.init(prop);
//utsi.init();
UserTransactionManager utm = new UserTransactionManager();
//utm.init();
utm.begin();
Transaction tx = utm.getTransaction();
XAConnection xamysql = mysql.getXAConnection();
XAResource db = xamysql.getXAResource();
tx.enlistResource(db);
Connection connection = xamysql.getConnection();
PreparedStatement stmt=connection.prepareStatement("SELECT ID, Name FROM city");
ResultSet rs = null;
rs = stmt.executeQuery("SELECT ID, Name FROM city");
while(rs.next())
{
System.out.println(rs.getInt("ID") + " " + rs.getString("Name"));
}
}
}
But i am getting an error,
log4j:WARN No appenders could be found for logger (com.atomikos.logging.LoggerFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main" java.lang.NoSuchMethodError: com.atomikos.persistence.imp.StateRecoveryManagerImp: method <init>()V not found
at com.atomikos.icatch.standalone.UserTransactionServiceImp.createDefault(UserTransactionServiceImp.java:205)
at com.atomikos.icatch.standalone.UserTransactionServiceImp.init(UserTransactionServiceImp.java:258)
at com.atomikos.icatch.config.UserTransactionServiceImp.init(UserTransactionServiceImp.java:405)
at com.atomikos.icatch.config.UserTransactionServiceImp.init(UserTransactionServiceImp.java:577)
at com.test.abcd.TestAtomikos.main(TestAtomikos.java:57)
I tried executing the same by integrating atomikos with tomcat and invoking a servlet which makes a call to the db. I got the same error, i tired checking the code of the StateRecoveryManagerImp online, i see the init method defined. I am not sure what is causing this issue. I tried just the database stuff, it worked fine, i was able to execute the query and get the results as well.
I tried using various versions of atomikos jars, but no luck. Any suggestions on how to get this fixed?
The exception that you get which is:
NoSuchMethodError:
com.atomikos.persistence.imp.StateRecoveryManagerImp: method ()V
not found
means that it tries at runtime to access to the default constructor (constructor with no arguments) of the class StateRecoveryManagerImp and it cannot find it.
This is a typically an exception that you face when you build your application with one version of your library and you run it against a different version that is not compatible.
Here as far as I can see from the source code, I believe that you compiled your code with transactions 3.9.0 or higher that has no constructor defined which means that we have the default constructor (as you can see here), and your application uses at Runtime an older version which has a constructor of type public StateRecoveryManagerImp ( ObjectLog objectlog ) which means that we have no default constructor (as you can see here) so when it tries to call it at runtime it fails.
To fix your issue simply check your classpath used at Runtime and make sure that you have only the version of transactions corresponding to the one used at compile time.
Related
I created a code that counts the number of files in a zipfile. I am currently outputting the information onto the console. I am not sure how to get started in putting the outputted information into a database table in Microsoft SQL server. I essentially just need to have it output to a table in Microsoft SQL server instead of outputting it to the console. I have the code below:
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class KZF
{
static int findNumberOfFiles(File file) {
try (ZipFile zipFile = new ZipFile(file)) {
return (int) zipFile.stream().filter(z -> !z.isDirectory()).count();
} catch (Exception e) {
return -1;
}
}
static String createInfo(File file) {
int tot = findNumberOfFiles(file) - 1;
return (file.getName() + ": " + (tot >= 0 ? tot + " files" : "Error reading zip file"));
}
public static void main(String[] args) throws IOException {
String dirLocation = "C:\\Users\\username\\Documents\\Temp\\AllKo";
try (Stream<Path> files = Files.list(Paths.get(dirLocation))) {
files
.filter(path -> path.toFile().isFile())
.filter(path -> path.toString().toLowerCase().endsWith(".zip"))
.map(Path::toFile)
.map(KZF::createInfo)
.forEach(System.out::println);
}
}
To interact with SQL-based databases in java, the 'base layer' is a library called JDBC. This works as follows:
JDBC itself is part of plain java just as much as java.io.File is. However, this is just the basic API you use to interact with Databases, it doesn't include support for any specific database. Here is the API.
You then need a so-called JDBC Driver; you'd need the JDBC driver for Microsoft SQL server. This driver needs to be on the classpath when you run your app; you don't need to reference any particular class file or 'load' it, just... make sure it's on the classpath, that's all you need. This jar, if on the classpath, automatically tells the JDBC system about its existence, and the JDBC system will then use it when you ask the JDBC system to connect to your microsoft sql database. Hence, nothing required except for this to be present on the classpath.
JDBC is intentionally a convoluted and hard to use API from the point of view of interacting with DBs from plain jane java code: It's the lowest denominator; the 'machine code' aspect. It needs to expose all possible DB functionality for all possible SQL-based database engines and give you the tools to run it in all possible modes. Thus, I strongly advise you not to program direct JDBC. Instead, use libraries that are built on top of JDBC and give you a nice, easy to understand API: Use JDBI or JOOQ, but I believe JOOQ is not free unless you use it with a free DB, and microsoft SQL isn't free, so be aware you may need to pay a license fee for JOOQ. JDBI is free.
In other words:
in your build system, add the com.microsoft.sqlserver :: mssql-jdbc :: 9.2.1.jre11 dependency.
in your build system, add the org.jdbi :: jdbi3-core :: 3.20.0 dependency.
Read the Microsoft SQL Server JDBC connector URL docs on how to build the so-called 'JDBC URL' which tells java how to connect to your microsoft SQL server.
Read the JDBI documentation. It's not hard - right on the front page you see the basic layout for how to send INSERT statements. (the URL you learned about in the previous doc? You pass that to the Jdbi.create() call).
Much easier, you can use the entries() method to get an Enumeration of the ZipEntry-s in the zip-file, and check each one to see if it isDirectory():
int countRegularFiles(final ZipFile zipFile) {
final Enumeration<? extends ZipEntry> entries = zipFile.entries();
int numRegularFiles = 0;
while (entries.hasMoreElements()) {
if (! entries.nextElement().isDirectory()) {
++numRegularFiles;
}
}
return numRegularFiles;
}
I am having trouble when executing a UDF with geoip2 (maxmind) as dependency under Hive 2.3.4 (java 8) the same code works fine under older versions of hive that use java 7 and also under Presto that use java 8.
I have tried using exact dependencies (maven) and manual compiling, multiple versions of hive, reducing the code and dependencies to bare minimum
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import com.maxmind.geoip2.record.City;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.exception.GeoIp2Exception;
public final class CityName extends UDF {
public String evaluate(String dbFile) throws IOException,GeoIp2Exception {
File database = new File(dbFile);
InetAddress ipAddress = InetAddress.getByName("127.0.0.1");
DatabaseReader reader = new DatabaseReader.Builder(database).build();
return "Database: "+dbFile.toString();
}
}
Error message
2019-05-21T16:31:56,631 ERROR [ce3bca33-87aa-4468-b1ed-7080e95efb2d main([])]: ql.Driver (SessionState.java:printError(1126)) - FAILED: SemanticException [Error 10014]: Line 1:7 Wrong arguments ''/root/GeoIP2-City.mmdb'': org.apache.hadoop.hive.ql.metadata.HiveException: Unable to execute method public java.lang.String com.example.hive.udf.CityName.evaluate(java.lang.String) throws java.io.IOException,com.maxmind.geoip2.exception.GeoIp2Exception,java.net.UnknownHostException with arguments {/root/GeoIP2-City.mmdb}:com.maxmind.geoip2.DatabaseReader.(Lcom/maxmind/geoip2/DatabaseReader$Builder;Lcom/maxmind/geoip2/DatabaseReader$1;)V
org.apache.hadoop.hive.ql.parse.SemanticException: Line 1:7 Wrong arguments ''/root/GeoIP2-City.mmdb'': org.apache.hadoop.hive.ql.metadata.HiveException: Unable to execute method public java.lang.String com.example.hive.udf.CityName.evaluate(java.lang.String) throws java.io.IOException,com.maxmind.geoip2.exception.GeoIp2Exception,java.net.UnknownHostException with arguments {/root/GeoIP2-City.mmdb}:com.maxmind.geoip2.DatabaseReader.(Lcom/maxmind/geoip2/DatabaseReader$Builder;Lcom/maxmind/geoip2/DatabaseReader$1;)V
at org.apache.hadoop.hive.ql.parse.TypeCheckProcFactory$DefaultExprProcessor.process(TypeCheckProcFactory.java:1367)
at org.apache.hadoop.hive.ql.lib.DefaultRuleDispatcher.dispatch(DefaultRuleDispatcher.java:90)
at org.apache.hadoop.hive.ql.lib.DefaultGraphWalker.dispatchAndReturn(DefaultGraphWalker.java:105)
.......
Caused by: java.lang.NoSuchMethodError: com.maxmind.geoip2.DatabaseReader.(Lcom/maxmind/geoip2/DatabaseReader$Builder;Lcom/maxmind/geoip2/DatabaseReader$1;)V
at com.maxmind.geoip2.DatabaseReader$Builder.build(DatabaseReader.java:160)
at com.example.hive.udf.CityName.evaluate(CityName.java:20)
... 47 more
We hit a very similar issue to that. In our case it turned out in the classpath of the Hive deployment there is an obsolete version of maxmind-db. This might even be by default on newer releases of Hive, but I haven't confirmed yet.
To fix, just shade any references to com.maxmind. Also, just to be safe, shade any any references to fasterxml.jackson as well - that's one of the core dependencies of GeoIP2 and conflicts of that in the classpath tend to cause weird runtime issues like this one. You can see an example of that in a PR addressing such issue in one of the Hive UDF GeoIP libs.
I have multiple System.out.println() calls in my program. My issue is that, after making a call to a DLL through a JNA Library (which does work without returning an error code or throwing an exception), subsequent calls to println() execute without printing anything! I know that the statements are executing because I'm stepping through them in NetBeans!
Unfortunately, I don't have a clue about the C code behind the DLL, and I guess you won't be able to duplicate this unless you register with qimaging.com and download the QCam SDK. I'm just wondering if anyone has experienced anything similar to this System.out.println() behavior, i.e. that it works until a certain point, then stops printing even though it executes.
This is my main test class:
package hwi.scope;
import com.sun.jna.ptr.IntByReference;
import hwi.scope.qcam.QCamDriverX64;
import java.io.File;
/**
* QCamTest class tests some functions of the QCam driver library.
* #author rnagel
*/
public class QCamTest
{
private static QCamDriverX64 driver;
// Main test method:
public static void main() throws Exception
{
// Set path to easily find DLL in the /dll folder:
File f = new File("dll");
System.setProperty("jna.library.path", f.getCanonicalPath());
// Use JNA to load the driver library:
driver = QCamDriverX64.INSTANCE;
// Load camera driver from the library:
loadQCamDriver();
// Print out the driver version:
printQCamVersion();
}
// Load camera driver method:
public static void loadQCamDriver()
{
System.out.println("Loading QCam driver..."); // Executes and prints to console
int error = driver.QCam_LoadDriver();
System.out.println("Done loading driver."); // Executes, but doesn't print to console
}
// Print camera driver version:
public static void printQCamVersion()
{
// Obtain driver version as a combination of 'major' and 'minor' increments:
IntByReference major = new IntByReference(), minor = new IntByReference();
int error = driver.QCam_Version(major, minor);
// At this point, I've verified that I have a obtained a valid version.
System.out.println("QCam v." + major.getValue() + "." + minor.getValue()); // Executes, but doesn't print to console
}
}
And this is the QCamDriverX64 class that I've made to wrap the DLL:
package hwi.scope.qcam;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;
/**
* QCamDriverX64 wraps the 64-bit version of the QCam driver DLL.
* #author rnagel
*/
public interface QCamDriverX64 extends Library {
// Make the library name publicly accessible:
public static final String DLL_NAME = "QCamDriverx64";
// Load an instance of the library using JNA:
public static final QCamDriverX64 INSTANCE = (QCamDriverX64) Native.loadLibrary(DLL_NAME, QCamDriverX64.class);
// Load the QCam driver:
int QCam_LoadDriver();
// Obtain QCam driver version # (in major and minor increments)
int QCam_Version (IntByReference major, IntByReference minor);
}
I'm using NetBeans 8.2 and JDK 1.8.0_121.
Thanks for taking a look! I'd appreciate any insight!
You can easily reproduce that by calling
System.out.close();
System.err.close();
I'm assuming that the native code in the DLL is doing something in that respect. It might be friendly by actually doing above call. In that case you could save System.out and System.err into variables, set some dummy streams with System.setOut() and System.setErr() and put everything back as it was before after the DLL-call. If the native code closes the underlying file handles, that won't help and the only option is to file a bug report at the provider of the DLL.
I have installed the local version of dynamoDB, and set up a maven java project to access the DB. When i run the code i get the below error. Since i have installed the server in local (it runs son localhost:8000), i dont have any credentials to provide...
Any idea how to solve it?
import java.util.Iterator;
import org.apache.commons.cli.ParseException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.TableCollection;
import com.amazonaws.services.dynamodbv2.exceptions.DynamoDBLocalServiceException;
import com.amazonaws.services.dynamodbv2.local.embedded.DynamoDBEmbedded;
import com.amazonaws.services.dynamodbv2.local.main.ServerRunner;
import com.amazonaws.services.dynamodbv2.local.server.DynamoDBProxyServer;
import com.amazonaws.services.dynamodbv2.model.ListTablesResult;
public class Test {
public static void main(String[] args) {
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().withEndpointConfiguration(
// we can use any region here
new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
.build();
DynamoDB dynamoDB = new DynamoDB(client);
//dynamoDB.listTables();
TableCollection<ListTablesResult> list = dynamoDB.listTables();
Iterator<Table> iterator = list.iterator();
System.out.println("Listing table names");
while (iterator.hasNext()) {
Table table = iterator.next();
System.out.println(table.getTableName());
}
System.out.println("over");
}
}
Error is
Exception in thread "main" com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain
at com.amazonaws.auth.AWSCredentialsProviderChain.getCredentials(AWSCredentialsProviderChain.java:131)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1115)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.runBeforeRequestHandlers(AmazonHttpClient.java:764)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:728)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:721)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:704)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:672)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:654)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:518)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.doInvoke(AmazonDynamoDBClient.java:1831)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:1807)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.listTables(AmazonDynamoDBClient.java:1123)
at com.amazonaws.services.dynamodbv2.document.internal.ListTablesCollection.firstPage(ListTablesCollection.java:46)
at com.amazonaws.services.dynamodbv2.document.internal.PageIterator.next(PageIterator.java:45)
at com.amazonaws.services.dynamodbv2.document.internal.IteratorSupport.nextResource(IteratorSupport.java:87)
at com.amazonaws.services.dynamodbv2.document.internal.IteratorSupport.hasNext(IteratorSupport.java:55)
Stumbled upon this when I was searching for the same problem. After half a day of wasting time, managed to solve the issue. Posting here in case anyone ever stumbles upon such situation again.
And the worst part? The solution I had to pierce through and experiment after going through thousands of pages, you would expect there to be some info about the problem. At the least, the documentation should have mentioned some note!
The solution :
Configuring AWS Credentials : go through that to set up some credential. Configure it as any random thing, it doesn't really matter.
Yeah, this was it!!
And for those ppl who are still lazy (like me ;-) ) to go through that, just follow the easiest of the methods :
Open the default config file : ~/.aws/credentials
Change the values in it to anything (like empty string here)
[default]
aws_access_key_id=''
aws_secret_access_key=''
Run the program. You can thank me later :D
I had a similar issue. To get around when running tests locally, I have added few lines to set java System properties.
System.setProperty(ACCESS_KEY_SYSTEM_PROPERTY, "accesskey"); System.setProperty(SECRET_KEY_SYSTEM_PROPERTY, "secretkey");
As per the Amazon Web Services documentation, Working with AWS Credentials
Official supported Java system properties are:
aws.accessKeyId
aws.secretKey
The following sets these system properties:
System.setProperty("aws.accessKeyId", "super-access-key");
System.setProperty("aws.secretKey", "super-secret-key");
This needs to be set before creating the Amazon DynamoDB client.
I am trying to print multiple copies of a pdf document. After googling around a bit I found that I have to put a Copies in a PrintRequestAttributeSet. But after doing this only 1 copy is printed instead of the amount I provided.
During debugging I can see that the print object changes its copies variable from 0 to 2, so I would assume I do everything correctly. I've also been playing around a bit with the collation and multipledocumenthandling variables, but the end result stays the same.
Does anyone know how I can get it to print the correct number of copies?
My code:
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.MultipleDocumentHandling;
import javax.print.attribute.standard.SheetCollate;
public class PrintTest {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
InputStream is = new BufferedInputStream(
new FileInputStream(
"<Insert pdf file here>"));
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
Copies copies = new Copies(2);
SheetCollate collate = SheetCollate.COLLATED;
MultipleDocumentHandling handling = MultipleDocumentHandling.SEPARATE_DOCUMENTS_COLLATED_COPIES;
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
pras.add(copies);
pras.add(collate);
pras.add(handling);
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob printJob = service.createPrintJob();
Doc doc = new SimpleDoc(is, flavor, null);
printJob.print(doc, pras);
}
}
So I've been playing around a bit more. I've added a few sysout statements using which I found out you have something called Fidelity which can be used to force it to reject the print job if it cannot be printed exactly as specified. But there are some issues with this. After adding the fidelity setting to it I end up with the following output:
[class javax.print.attribute.standard.JobName, class javax.print.attribute.standard.RequestingUserName, class javax.print.attribute.standard.Copies, class javax.print.attribute.standard.Destination, class javax.print.attribute.standard.OrientationRequested, class javax.print.attribute.standard.PageRanges, class javax.print.attribute.standard.Media, class javax.print.attribute.standard.MediaPrintableArea, class javax.print.attribute.standard.Fidelity, class javax.print.attribute.standard.SheetCollate, class sun.print.SunAlternateMedia, class javax.print.attribute.standard.Chromaticity, class javax.print.attribute.standard.Sides, class javax.print.attribute.standard.PrinterResolution]
[]
Exception in thread "main" sun.print.PrintJobAttributeException: unsupported attribute: collated
at sun.print.Win32PrintJob.getAttributeValues(Win32PrintJob.java:667)
at sun.print.Win32PrintJob.print(Win32PrintJob.java:332)
at net.pearlchain.print.distribute.jasper.PrintTest.main(PrintTest.java:52)
The unsupported attribute is different with each execution but always one of the attributes I have set. I have tried running it using java 6 and java 7 and the only difference I get is the line on which the exception is thrown. On java 6 it is on line 667 and on java 7 it is line 685. Looking at the code found at grepcode I can see the exception being thrown but the actual reason is unclear.
Ok, I've found out why this happens, the flavor I've selected does not support multiple copies. Setting it to pdf leads me to getting a flavornotsupported exception because I have no printers installed which support printing from a pdf source.
It's been a long time and I forgot to post my solution here for future visitors.
I solved this by adding a 3rd party pdf library (Apache PDFBox) which provided me with an inputstream which I could send to the printer with all the settings I required.
http://pdfbox.apache.org/
I no longer have access to the code but this could be useful for future visitors. :)