JasperReports: calling report from jar - java

I'm using JasperReports 4.7.1 plugin for NetBeans 7.2 to generate report from mysql database
and while I run the application from the ide there is no problem found accept this warnings:
log4j:WARN No appenders could be found for logger (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
log4j:WARN Please initialize the log4j system properly.
But the report generated and viewed correctly.
The problem is while I clean and build the application then rung it from the jar file the report does not generated and does not give me any exceptions just no reports viewed and every thing else is normal?
This is the function I use for viewing the report in JasperViewer:
public void printInvoice(int invid) throws IOException {
try {
String sql = "SELECT\n" +
" ordersdetails.`ITEMNAME` AS ordersdetails_ITEMNAME,\n" +
" ordersdetails.`AMOUNT` AS ordersdetails_AMOUNT,\n" +
" ordersdetails.`PRICE` AS ordersdetails_PRICE,\n" +
" invoices.`INVOICEID` AS invoices_INVOICEID,\n" +
" invoices.`CUSTOMER` AS invoices_CUSTOMER,\n" +
" invoices.`THEDATE` AS invoices_THEDATE,\n" +
" invoices.`COST` AS invoices_COST\n" +
"FROM\n" +
" `invoices` invoices RIGHT OUTER JOIN `ordersdetails` ordersdetails ON invoices.`INVOICEID` = ordersdetails.`INVOICE` where invoices.invoiceid=" + invid;
InputStream in = this.getClass().getResourceAsStream("/reports/invoice.jrxml");
JasperDesign jd = JRXmlLoader.load(in);
JRDesignQuery q = new JRDesignQuery();
q.setText(sql);
jd.setQuery(q);
JasperReport jasp_rep = JasperCompileManager.compileReport(jd);
JasperPrint jasp_print = JasperFillManager.fillReport(jasp_rep, null, mc.getConnection());
JasperViewer.viewReport(jasp_print, false);
} catch (JRException e) {
JOptionPane.showMessageDialog(null, e.getMessage());
System.out.println(e);
}
}

Propably load the report from the wrong location, try relative path:
InputStream in = this.getClass().getResourceAsStream("reports/invoice.jrxml");
That means there is the invoice.jrxml in the report folder and that folder is at same level as the class (this.getClass()) that invokes getResourceAsStream.
Additionaly you can get around the warning with
org.apache.log4j.BasicConfigurator.configure();
at beginning of your program.

Do not run the jar file directly. Instead, run it from the command line using java -jar myjar.jar as #PeterMmm has said in the comments above and you will see the errors listed. Try to find the error from that. I think the error is probably a NoClassDefFoundError and it is due to a wrong version of a library file. If that is the reason, download a correct version of the library jar file which contain the missing class definitions and add it to the project library and build the project.

Related

How to fix resource changed on src filesystem issue

I'm trying to use Hive on MR executing SQL and it fails half way with errors below:
Application application_1570514228864_0001 failed 2 times due to AM Container for appattempt_1570514228864_0001_000002 exited with exitCode: -1000
Failing this attempt.Diagnostics: [2019-10-08 13:57:49.272]Failed to download resource { { s3a://tpcds/tmp/hadoop-yarn/staging/root/.staging/job_1570514228864_0001/libjars, 1570514262820, FILE, null },pending,[(container_1570514228864_0001_02_000001)],1132444167207544,DOWNLOADING} java.io.IOException: Resource s3a://tpcds/tmp/hadoop-yarn/staging/root/.staging/job_1570514228864_0001/libjars changed on src filesystem (expected 1570514262820, was 1570514269265
The key message from the error log from my perspective is libjars changed on src filesystem (expected 1570514262820, was 1570514269265. There are several threads about this issue at SO but not been answered yet, like thread1 and thread2.
I found something valuable from apache jira and redhat bugzilla. I synced clock by NTP through all nodes related. But same issue is still there.
Any comment is welcomed, thx.
I still didn't know why the timestamp of resource file is inconsistent and there isn't a way to fix it in configuration way, AFAIK.
However, I managed to find a workaround to skip the issue. Let me summarize it here for anyone who might run into same issue.
By checking error log and search it at Hadoop source code, we can trace the issue at hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/FSDownload.java.
Just remove the exception throwing statements,
private void verifyAndCopy(Path destination)
throws IOException, YarnException {
final Path sCopy;
try {
sCopy = resource.getResource().toPath();
} catch (URISyntaxException e) {
throw new IOException("Invalid resource", e);
}
FileSystem sourceFs = sCopy.getFileSystem(conf);
FileStatus sStat = sourceFs.getFileStatus(sCopy);
if (sStat.getModificationTime() != resource.getTimestamp()) {
/**
throw new IOException("Resource " + sCopy +
" changed on src filesystem (expected " + resource.getTimestamp() +
", was " + sStat.getModificationTime());
**/
LOG.debug("[Gearon][Info] The timestamp is not consistent among resource files.\n" +
"Stop throwing exception . It doesn't affect other modules. ");
}
if (resource.getVisibility() == LocalResourceVisibility.PUBLIC) {
if (!isPublic(sourceFs, sCopy, sStat, statCache)) {
throw new IOException("Resource " + sCopy +
" is not publicly accessible and as such cannot be part of the" +
" public cache.");
}
}
downloadAndUnpack(sCopy, destination);
}
Build hadoop-yarn-project and copy 'hadoop-yarn-common-x.x.x.jarto$HADOOP_HOME/share/hadoop/yarn`.
Leave this thread here and thanks for any further explanation about how to fix it without changing hadoop source.
I had to do the same , this should be configurable, even small latency will fail the execution, this might happen, if one changes the hadoop file system to use s3 and run MR program , Note* please make sure, you are using same jdk version to generate the jar as mentioned in apache hadoop docs for your hadoop version, else you might run into errors.

Manually loading native libraries to circumvent a restrictive environment

I'm maintaining a Java Swing application that requires a connection to an instance of Microsoft SQL Server. For various reasons, I opted to replace the native SQL Server driver being used with jTDS (the aforementioned Microsoft drivers were not working at the time and have apparently failed in the field as well). When I try to run the executable .jar outside of the IDE, I run into issues because I'm missing the appropriate ntlmauth.dll dependency.
Before proceeding, it's important to note that this application is being developed and used in an extremely restrictive (Windows-only) environment:
I cannot install any software that requires Windows UAC authentication
My users cannot install or run any software that requires UAC authentication
This currently means I cannot write files to System32 or JAVA_HOME, and cannot use any sort of ProcessBuilder tomfoolery to start another JVM with whatever command line arguments I need
I cannot use executable wrappers/installers that would only require the UAC permission for the first time installation/setup
The solution I'm trying is a combination of this one and this one to check it--essentially packaging the .dll inside of the .jar, then extracting it and loading it if necessary--as most of the other solutions I've found have been incompatible with the above restrictions; however, I'm running into an issue where even after the native library is ostensibly "loaded," I get an exception saying it isn't.
My pre-startup code:
private static final String LIB_BIN = "/lib-bin/";
private static final String JTDS_AUTH = "ntlmauth";
// load required JTDS binaries
static {
logger.info("Attempting to load library {}.dll", JTDS_AUTH);
try {
System.loadLibrary(JTDS_AUTH);
} catch (UnsatisfiedLinkError e) {
loadFromJar();
}
try {
// do some quick checks to make sure that went ok
NativeLibraries nl = new NativeLibraries();
logger.debug("Loaded libraries: {}", nl.getLoadedLibraries().toString());
} catch (NoSuchFieldException ex) {
logger.info("Native library checker load failed", ex);
}
}
/**
* When packaged into JAR extracts DLLs, places these into
*/
private static void loadFromJar() {
// we need to put DLL in temp dir
String path = ***;
loadLib(path, JTDS_AUTH);
}
/**
* Puts library to temp dir and loads to memory
*/
private static void loadLib(String path, String name) {
name = name + ".dll";
try {
// have to use a stream
InputStream in = net.sourceforge.jtds.jdbc.JtdsConnection.class.getResourceAsStream(LIB_BIN + name);
// always write to different location
File fileOut = new File(System.getProperty("java.io.tmpdir") + "/" + path + LIB_BIN + name);
logger.info("Writing dll to: " + fileOut.getAbsolutePath());
OutputStream out = FileUtils.openOutputStream(fileOut);
IOUtils.copy(in, out);
in.close();
out.close();
System.load(fileOut.toString());
} catch (Exception e) {
logger.error("Exception with native library loader", e);
JOptionPane.showMessageDialog(null, "Exception loading native libraries: " + e.getLocalizedMessage(), "Exception", JOptionPane.ERROR_MESSAGE);
}
}
As you can see, I basically copied the solution from the first link verbatim, with a few minor modifications just to try and get the application running. I also copied the class from the second link and named it NativeLibraries, the invocation of that method is fairly irrelevant but it shows up in the logs.
Anyway here are the relevant bits of the log output on starting up the application:
2015-07-20 12:32:33 INFO - Attempting to load library ntlmauth.dll
2015-07-20 12:32:33 INFO - Writing dll to: C:\Users\***\lib-bin\ntlmauth.dll
2015-07-20 12:32:33 DEBUG - Loaded libraries: [C:\Program Files\Java\jre1.8.0_45\bin\zip.dll, C:\Program Files\Java\jre1.8.0_45\bin\prism_d3d.dll, C:\Program Files\Java\jre1.8.0_45\bin\prism_sw.dll, C:\Program Files\Java\jre1.8.0_45\bin\msvcr100.dll, C:\Program Files\Java\jre1.8.0_45\bin\glass.dll, C:\Program Files\Java\jre1.8.0_45\bin\net.dll, C:\Users\***\lib-bin\ntlmauth.dll]
2015-07-20 12:32:33 INFO - Application startup
***
2015-07-20 12:32:36 ERROR - Database exception
java.sql.SQLException: I/O Error: SSO Failed: Native SSPI library not loaded. Check the java.library.path system property.
at net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:654) ~[jtds-1.3.1.jar:1.3.1]
at net.sourceforge.jtds.jdbc.JtdsConnection.<init>(JtdsConnection.java:371) ~[jtds-1.3.1.jar:1.3.1]
at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:184) ~[jtds-1.3.1.jar:1.3.1]
at java.sql.DriverManager.getConnection(Unknown Source) ~[na:1.8.0_45]
at java.sql.DriverManager.getConnection(Unknown Source) ~[na:1.8.0_45]
One can see that the library was, indeed, "loaded," from the third line in the log (it's the last entry, if you don't feel like scrolling). However, I simply used the class that I felt like was probably using the native libraries (I also tried the TdsCore class to no avail), as the example that showed how to do this was just using a random class from the package the library was needed in.
Is there something I'm missing here? I'm not very experienced with the JNI or the inner workings of ClassLoaders, so I might just be loading it wrong. Any advice or suggestions would be greatly appreciated!
Welp I figured out a workaround: I ended up using JarClassLoader. This basically entailed copying all my dependencies, both Java and native, into a "libraries" folder within my main .jar, and disabling .jar signing in the IDE. The application is then run by a new class that simply creates a new JarClassLoader object and running the "invokeMain" method--an example is on the website. The whole thing took about three minutes, after several days of banging my head against a wall.
Hope this helps someone someday!

Connecting to Netbeans SQL Database for the first time - java.sql.SQLException: No suitable driver found 0 08001

I am fairly new to Java, so I bought a book to learn from. Everything went swimmingly until I got to the chapter on SQL. I am working in NetBeans with the sample database, but I can't get the database to connect with the program.
Here's the code I faithfully copied from the book:
import java.sql.*;
public class SysTableReporter {
public static void main(String[] arguments) {
String data = "jdbc:derby://localhost:1527/sample";
try (
Connection conn = DriverManager.getConnection(
data, "app", "APP");
Statement st = conn.createStatement()) {
System.out.println("TABLEID:\t" );
Class.forName("org.apache.derby.jdbc.ClientDriver");
ResultSet rec = st.executeQuery(
"select * " +
"from SYS.SYSTABLES " +
"order by TABLENAME");
while(rec.next()) {
System.out.println("TABLEID:\t" + rec.getString(1));
System.out.println("TABLENAME:\t" + rec.getString(2));
System.out.println("TABLETYPE:\t" + rec.getString(3));
System.out.println("SCHEMAID:\t" + rec.getString(4));
System.out.println();
}
st.close();
} catch (SQLException s) {
System.out.println("SQL Error: " + s.toString() + " "
+ s.getErrorCode() + " " + s.getSQLState());
} catch (Exception e) {
System.out.println("Error: " + e.toString() + e.getMessage());
}
}
}
Here's what my Services Panel looks like:
Click to view Image
Here's my output:
SQL Error: java.sql.SQLException: No suitable driver found for jdbc:derby://localhost:1527/sample 0 08001
At first I figured I just had some typo, but looking over it carefully I can't find it. I tried installing a new JDBC driver, but that didn't seem to help either. I'm running a Windows 8 laptop, and I have the telnet client turned on. My best guess at this point is that I somehow missed a step in the initial setup, but I can't find it to go back and fix it. Any help would be great.
You are probably just missing the Derby JDBC driver jar in your project's library section (I'm assuming that you created a standard Netbeans project, not a Maven type project). The jar is called derbyclient.jar.
The easiest way to solve this:
locate derbyclient.jar eg with Explorer
in Netbeans, rightclick on the project node in the Projects pane.
Select Properties, and there select libraries
Click "Add JAR/Folder", navigate to derbyclient.jar
That effectively adds the jar to your project. Just recompile, run and everything should work as intended.
EDIT: aside from #BobKuhar's find, another problem with the given code is that it doesn't use one of Java's more powerful debugging mechanisms, the stacktrace. At its most basic form, showing them on screen is simple, not more than
} catch (SQLException s) {
System.out.println("SQL Error: " + s.toString() + " "
+ s.getErrorCode() + " " + s.getSQLState());
// and show us the stacktrace
s.printStackTrace();
} catch (Exception e) {
System.out.println("Error: " + e.toString() + e.getMessage());
// and show us the stacktrace
e.printStackTrace();
}
the stack trace will not only show you the exact line at which the error occurred, but also the trajectory to the exception (how the program got there), invaluable in more complicated programs. Definitely something you want to learn to use!
Lots of info on stack traces here: What is a stack trace, and how can I use it to debug my application errors?
I think what you really have is just a sequencing problem. The Class.forName call registers the driver with the DriverManager (I think). This needs to occur before you attempt to establish a Connection through the DriverManager.
Class.forName( "org.apache.derby.jdbc.ClientDriver" ).newInstance();
Connection conn = DriverManager.getConnection( data, "app", "APP");
If this gives you some "ClassNotFound" exception, then fvu's assertion that you don't have the Derby JDBC Jar on the class path is your next issue.
The Derby docs have an example: http://db.apache.org/derby/integrate/plugin_help/derby_app.html

Java Trouble compiling maxmind geoip LookupService class

I wonder if some one can please help as I am struggling to compile maxmind.geoip.LookupService.java
I have downloaded geoip-api-1.2.10.jar for inclusion in WEB-INF\lib and I have referenced it in my classes path, but it just won't compile.
I have compiled the following successfully so I'm a bit at a loss:
com.maxmind.geoip.Country
com.maxmind.geoip.DatabaseInfo
com.maxmind.geoip.Location
com.maxmind.geoip.Region
com.maxmind.geoip.timeZone
Can't seem to find a full set of compiled java classes for com.maxmind.geoip, any help would be much appreciated :-)
I resolved this by downloading the latest java files from http://dev.maxmind.com/geoip/legacy/downloadable/ unpacked the folder and then opened a command prompt and typed the following:
cd source/com/maxmind/geoip/
javac *.java
I'm using jdk1.6.0_34 and all classes compiled with no errors.
I copied the com.maxmind.geoip folder to \WEB-INF\classes and downloaded geoip-api-1.2.10.jar and placed that in the WEB-INF\lib folder.
Finally I download GeoIP.dat from http://dev.maxmind.com/geoip/legacy/geolite/ and placed it in a new folder called GeoIP under webapps so that all my applications can use it.
The following code is to obtain the country code from a users IP Address:
import com.maxmind.geoip.*;
import java.io.IOException;
class CountryLookupTest {
public static void main(String[] args) {
try {
String sep = System.getProperty("file.separator");
String dir = "C:/Program Files/Apache Software Foundation/Tomcat 7.0/GeoIP";
String dbfile = dir + sep + "GeoIP.dat";
LookupService cl = new LookupService(dbfile,LookupService.GEOIP_MEMORY_CACHE);
System.out.println(cl.getCountry("151.38.39.114").getCode());
System.out.println(cl.getCountry("151.38.39.114").getName());
System.out.println(cl.getCountry("12.25.205.51").getName());
System.out.println(cl.getCountry("64.81.104.131").getName());
System.out.println(cl.getCountry("200.21.225.82").getName());
cl.close();
}
catch (IOException e) {
System.out.println("IO Exception");
}
}
}
Hope this proves useful to others.
According to the MaxMind dev site, the API is available on the Maven Central Repository. You shouldn't need to compile anything unless you downloaded the source package.
You have to download a Jar file called geoIP-api from this link to maven repository,In case you haven't downloaded the other Jar files from go this geoIP2 also don't forget to download the .DAT file from geoIP.dat. Then add the files to your project class path from project properties and then libraries finally add Jar in netbeans.
Now use this code:
public String IpGeoLocation(String IP) {
try {
String dbfile = "C:\\Users\\User Name \\Documents\\NetBeansProjects\\IP Tools\\resources/GeoIP.dat";
String location = "";
LookupService cl = new LookupService(dbfile, LookupService.GEOIP_MEMORY_CACHE);
location = cl.getCountry(IP).getName() + " " + cl.getCountry(IP).getCode();
cl.close();
return location;
} catch (Exception e) {
return "Error";
}
}
I was able to find the country and country code only !!

jrxml does not compiling

Hi i have problem in jasper reports.. im executing jrxml through my java class shown below
String jrxmlPath = context.getRealPath("//IREPORT_JRXML//" + reportPath);
System.out.println("in BTO report Selected " +jasperReport); ---->(1)
JasperReport jasperReport = JasperCompileManager.compileReport(jrxmlPath);
System.out.println("in BTO report compiled " +jasperReport); ----->(2)
"//IREPORT_JRXML// is the path where i put jrxml file. i executed my application control is executing up to ---->(1) line but it doesnt executing belo statements,here the problem is at lest i doesnt showing any error on console.
im using IReport 4.0.2,tomcat 7,jdk 1.7 , i added jasperreport-3.7.4.jar file in lib folder.
is there any issue about version problems? IReport 4.0.2,tomcat 7,jdk 1.7 and web dynamic Module 3.0
i tried to find out the problem unfortunately i missed some library... but i dint remember which library it is ... jasper compiler doesnt executing report design elements,report without design elements is executing , can anybody tell me wat library / jar i need to add for executing report design elements.....
Please try the following code
`ServletContext context = getServletContext();
String reportPath = context
.getRealPath("/WEB-INF/reports/filname.jasper");
JasperReport jasperReport =
JasperCompileManager.compileReport(reportPath);`

Categories