How to fix resource changed on src filesystem issue - java

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.

Related

How can I create executable jars with embedded tomcat 9?

Has anyone tried the plugin to build an executable war/jar using Tomcat 9?
I attempted to do so however ran into:
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.catalina.startup.Catalina.setConfig(Ljava/lang/String;)V
at org.apache.tomcat.maven.runner.Tomcat7Runner.run(Tomcat7Runner.java:240)
at org.apache.tomcat.maven.runner.Tomcat7RunnerCli.main(Tomcat7RunnerCli.java:204)
I looked at the source and changed Catalina.setConfig() to Catalina.setConfigFile() based on docs here. After doing so the .extract dir is just empty:
use extractDirectory:.extract populateWebAppWarPerContext
warValue:ROOT.war|ROOT populateWebAppWarPerContext
contextValue/warFileName:ROOT/ROOT.war webappWarPerContext entry
key/value: ROOT/ROOT.war expand to file:.extract/webapps/ROOT.war
Exception in thread "main" java.lang.Exception: FATAL: impossible to
create directories:.extract/webapps at
org.apache.tomcat.maven.runner.Tomcat7Runner.extract(Tomcat7Runner.java:586)
at
org.apache.tomcat.maven.runner.Tomcat7Runner.run(Tomcat7Runner.java:204)
at
org.apache.tomcat.maven.runner.Tomcat7RunnerCli.main(Tomcat7RunnerCli.java:204)
.... although there is a ROOT.war, server.xml, web.xml in the *-exec-war.jar.
Is there a better way to be creating exec-jars with embedded tomcat 9?
For those looking for a solution it was fairly straight forward to checkout the code for the plugin and make a few changes to get this to work. Namely:
Update POM to change the depends to Tomcat 9
Fix compile errors which generally stem from deprecated methods. The lookup on these methods can be found here. For example:
- container.setConfig( serverXml.getAbsolutePath() );
+ container.setConfigFile( serverXml.getAbsolutePath() );
... and ...
- staticContext.addServletMapping( "/", "staticContent" );
+ staticContext.addServletMappingDecoded( "/", "staticContent" );
There are a few others but generally not difficult to resolve. After doing so I updated my app's pom to use the modified version and was able to generate a Tomcat 9 exec jar.
I would love to hear what others are doing here. I know some are programmatically initializing Tomcat via a new Tomcat() instance however curious what other solutions exist ready made. Thanks
For future searchs, one solution is to use the DirResourceSet or JarResourceSet.
String webAppMount = "/WEB-INF/classes";
WebResourceSet webResourceSet;
if (!isJar()) {
webResourceSet = new DirResourceSet(webResourceRoot, webAppMount, getResourceFromFs(), "/");
} else {
webResourceSet = new JarResourceSet(webResourceRoot, webAppMount, getResourceFromJarFile(), "/");
}
webResourceRoot.addJarResources(webResourceSet);
context.setResources(webResourceRoot);
public static boolean isJar() {
URL resource = Main.class.getResource("/");
return resource == null;
}
public static String getResourceFromJarFile() {
File jarFile = new File(System.getProperty("java.class.path"));
return jarFile.getAbsolutePath();
}
public static String getResourceFromFs() {
URL resource = Main.class.getResource("/");
return resource.getFile();
}
When add the webapp, use root path "/" for docBase:
tomcat.addWebapp("", "/")
Credits for:
https://nkonev.name/post/101

java rmi simple project classNotFoundException binding registry

Ok, I'm sure this should be pretty easy, but I'm fairly new to Java (I'm more a .NET boy :P) and after following every single recommendation I found here to no success, I think it's time to step back and ask.
I'm trying to start a simple rmi project with a client, a server and a common project where common interfaces are defined. I've just implemented my server code, and when I try to run it to check if everything is fine, I get struck on a java.lang.ClassNotFoundException.
After following several answers on similar issues, I'm fair sure that my problem comes from rmiregistry running on a different location than my project.
I use following code to set registry codebase:
public class Utils {
public static final String CODEBASE = "java.rmi.server.codebase";
public static void setCodeBase(Class<?> c) {
String ruta = c.getProtectionDomain().getCodeSource().getLocation().toString();
String path = System.getProperty(CODEBASE);
if (path != null && !path.isEmpty()) {
ruta = path + " " + ruta;
}
System.setProperty(CODEBASE, ruta);
}
}
Then, I try to start my server code with this main class:
public class MainRegulador {
public static void main(String[] args) throws AccessException, RemoteException, NotBoundException {
Utils.setCodeBase(IRegulador.class);
Registry registro = null;
Remote proxy = null;
try {
Regulador myReg = new Regulador();
proxy = UnicastRemoteObject.exportObject(myReg, 36510);
registro = LocateRegistry.getRegistry();
registro.rebind("Distribuidor", proxy); //this is the line where exception is thrown
System.out.println("El Regulador está corriendo. Pulse ENTER para finalizar el proceso.");
System.in.read();
} catch(Exception ex) {
System.out.println("No se ha logrado inicializar el Registrador");
System.out.println(ex.getMessage());
} finally {
if (registro != null && proxy != null) {
registro.unbind("Distribuidor");
UnicastRemoteObject.unexportObject(proxy, true);
}
}
}
}
But when I run it, always get a java.lang.ClassNotFoundException at IRegulador interface.
Now the fun part:
I've printed to console java.rmi.server.codebase value, and it's pointing to bin folder of project where IRegulador interface is defined. (file:/F:/Practicas%20y%20dem%c3%a1s/Sistemas%20Distribuidos/common/bin/)
Obviously, that project is also set in the classpath of server project
(Regulador)
Workspace and rmiregistry are on different disks
Despite all, it doesn't seem a global classpath problem, as Utils class is on the same project as IRegulador interface, and it runs before the exception is thrown (as java.rmi.server.codebase is correctly set).
I've tried to set the classpath of rmiregistry before calling it (although it is directly discouraged on some answers), but nothing changed.
I've also tried to start rmiregistry.exe from Regulador project bin folder, but also seemed to don't change anything.
Coming from a .NET background, I've always found these classpath issues confusing, and this one is starting to consume much more time than I suspect it deserves. I'm in desperate need of help.
UPDATE: I'm starting to think that the problem is within the url it's passed to the codebase from IRegulador.class. If I paste it into windows explorer, the SO is unable to locate it, so I supose that it's being built with some structure problem that prevents the registry to reach the route:
file:/F:/Practicas%20y%20dem%c3%a1s/Sistemas%20Distribuidos/common/bin/
UPDATE2: I thought path route could be too complex, so I decided to simplify it and strip it from any non-straight character. Now codebase value is
file:/F:/Practicas/SD/common/bin/
However the problem persists, I don't know why rmiregistry is unable to reach that folder.
Then I decided to move the whole project to the same disk where rmiregistry is executed, and see if it changes anything. But nothing changed, same problem.
Ok, finally I got it working...
I've just copied rmiregistry.exe into the common/bin folder and launch it directly from there (previously just had called from there).
This seems to fix the problem with the routes (actually it makes the route available to the registry as it's on the same folder, probably all my codebase writting code is superflous now).

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!

JasperReports: calling report from jar

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.

How do i dump errors reported by logger.error into a file

I have a selenium script and I need to write the failures to a log file. i am using the logger.info() method to dump the required information into my file but i need to maintain a seperate errorlog file that contains all info that i dump using logger.error() method. Can anybody help me with this???
my code is somewhat like below:
if (isCasePass == true)
{
logger.info("TESTCASE CASE PASS");
}
else
{
logger.error("TESTCASE CASE FAILED");
}
logger.info("SOURCE FILE NUMBER : " + key + " : END" );
you must configure log4j.properties file.
see links:
http://www.theserverside.com/discussions/thread.tss?thread_id=31659
http://www.mkyong.com/logging/log4j-log4j-properties-examples/

Categories