I am using group: 'com.facebook.ads.sdk', name: 'facebook-java-ads-sdk', version: '0.4.0'
On com.dan.dadl.ccr.process.facebook.APIContext there is method setLogger(PrintStream logger)
By default this logs to System.out
I would like to log the rest calls to the application's log. The application is using log4j2.
Can anyone advise me how to do this?
To do it you need change the system.out PrintStream. You need the next code lines to do it.
public String getLoggerFileName() {
org.apache.logging.log4j.core.Logger loggerImpl = (org.apache.logging.log4j.core.Logger) log;
Appender appender = loggerImpl.getAppenders().get("FileAppender");
// Unfortunately, File is no longer an option to return, here.
return ((FileAppender) appender).getFileName();
}
final static Logger log = LogManager.getLogger(WebApplicationInitializer.class);
On static block or entry point of your app you need to add these lines:
//redirect sysout to log
File file = new File(getLoggerFileName());
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
PrintStream ps = new PrintStream(fos);
System.setOut(ps);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
So, all output by System.out.println will be redirected to file.
Related
I am using jersey for building rest service which will upload a file. But I am facing problem in writing a file to required location. Java throws a system cannot find specified path error. Here is my Web service :
#POST
#Path("/fileupload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(#FormDataParam("file")InputStream fileUploadStream, #FormDataParam("file")FormDataContentDisposition fileDetails) throws IOException{
StringBuilder uploadFileLocation= new StringBuilder();
uploadFileLocation.append("c:/logparser/webfrontend/uploads");
uploadFileLocation.append("/"+dateFormat.format(Calendar.getInstance().getTime()));
uploadFileLocation.append("/"+fileDetails.getFileName());
writeToFile(fileUploadStream, uploadFileLocation.toString());
return Response.status(200).entity("File saved to " + uploadFileLocation).build();
}
private void writeToFile(InputStream uploadInputStream, String uploadFileLocation)
{
log.debug("UploadService , writeToFile method , start ()");
try{
int read = 0;
byte[] bytes = new byte[uploadInputStream.available()];
log.info("UploadService, writeToFile method , copying uploaded files.");
OutputStream out = new FileOutputStream(new File(uploadFileLocation));
while ((read = uploadInputStream.read(bytes)) != -1)
{
out.write(bytes, 0, read);
}
out.flush();
out.close();
}
catch(Exception e)
{
log.error("UploadService, writeToFile method, error in writing to file "+e.getMessage());
}
}
From looking at just the code (it's usually helpful to include the exception and stack trace), you're trying to write to a directory based on a timestamp which doesn't exist yet. Try adding a call to File.mkdir/mkdirs. See this question/answer: FileNotFoundException (The system cannot find the path specified)
Side note - Unless you have a reason not to, I'd consider using something like Apache commons-io(FileUtils.copyInputStreamToFile) to do the writing.
I'm trying to connect to a ForexTrading broker FIX API and do some trading.
I tried my best to read through the Quickfix for .net. and almost understand the process of how the quickfix works. However, when I try to initiate the socketinitiator, I failed to do that and there are no complaints and exceptions from VS 2012. It is simply stuck there.
Here's my code:
private void iFind_ItemClick(object sender, ItemClickEventArgs e)
{
try
{
QuickFix.SessionSettings settings = new QuickFix.SessionSettings("C:\\Users\\Administrator\\Documents\\My Box Files(shewenhao#hotmail.com)\\Work With Mr.Liu\\ForexAutoTradingSystem\\ForexAutoTradingSystem\\integralfix.cfg");
IntegralFixAPI integralFixAPIApplication = new IntegralFixAPI();
QuickFix.IMessageStoreFactory storeFactory = new QuickFix.FileStoreFactory(settings);
QuickFix.ILogFactory logFactory = new QuickFix.ScreenLogFactory(settings);
QuickFix.Transport.SocketInitiator initiator = new QuickFix.Transport.SocketInitiator(
integralFixAPIApplication, storeFactory, settings, logFactory);
MessageBox.Show(settings.ToString());
integralFixAPIApplication.MyInitiator = initiator;
initiator.Start();
while (true)
{
Thread.Sleep(200);
MessageBox.Show("true");
}
//initiator.Stop();
}
catch (System.Exception systeme)
{
Console.WriteLine(systeme.Message);
Console.WriteLine(systeme.StackTrace);
}
}
You may notice that I have a MessageBox right below the SocketInitiator and it pops up before this QuickFix.Transport.SocketInitiator line. I do not get it that why I failed at this point. On the page of quickfix .Net http://quickfixn.org/tutorial/creating-an-application, it says that you simply need to replace the threadedacceptor with the socketinitiator. However, I can not pass through this initiation line.
I have produced a fop.dll from fop-1.0 with ikvm:
ikvmc -target:library -reference:IKVM.OpenJDK.Core.dll -recurse:{myPathToJars}\*.jar -version:1.0 -out:{myPathToJars}\fop.dll
If I use my fop.dll in a Windows Application, everything works perfect.
If I use it in a Class Library, I get the following error:
"Provider com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl not found" at javax.xml.transform.TransformerFactory.newInstance()
The code line is: TransformerFactory factory = TransformerFactory.newInstance();
Here is the code of method:
public static void xmlToPDF(String xmlPath, String xslPath, SortedList arguments, String destPdfPath)
{
java.io.File xmlfile = new java.io.File(xmlPath);
java.io.File pdffile = new java.io.File(destPdfPath);
try
{
// configure fopFactory as desired
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// configure foUserAgent as desired
// Setup output
OutputStream outputStream = new java.io.FileOutputStream(pdffile);
outputStream = new java.io.BufferedOutputStream(outputStream);
try
{
// Construct fop with desired output format
Fop fop = fopFactory.newFop("application/pdf" /*MimeConstants.MIME_PDF*/, foUserAgent, outputStream);
// Setup XSLT
TransformerFactory factory = TransformerFactory.newInstance();
java.io.File xsltfile = new java.io.File(xslPath);
Transformer transformer = factory.newTransformer(new StreamSource(xsltfile.getAbsoluteFile()));
// Set the value of a in the stylesheet
if (arguments != null)
{
IList keys = arguments.GetKeyList();
foreach (var key in keys)
{
Object value = arguments[key];
transformer.setParameter(key.ToString(), value);
}
}
// Setup input for XSLT transformation
Source src = new StreamSource(xmlfile);
// Resulting SAX events (the generated FO) must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
transformer.transform(src, res);
}
catch (Exception e1)
{
System.Console.WriteLine(e1.Message);
}
finally
{
outputStream.close();
}
}
catch (Exception ex)
{
System.Console.WriteLine(ex.Message);
}
}
I used ikvm-0.46.0.1 to make my fop.dll (based on fop 1.0). I included the following jars:
avalon-framework-4.2.0.jar
batik-all-1.7.jar
commons-io-1.3.1.jar
commons-logging-1.0.4.jar
fop.jar
serializer-2.7.0.jar
xalan-2.7.0.jar
xercesImpl-2.7.1.jar
xml-apis-1.3.04.jar
xml-apis-ext-1.3.04.jar
xmlgraphics-commons-1.4.jar
Any idea why this error occurs? Why is the behaviour different between Windows Application and Class Library?
Addition 10/19/11:
I managed to get working the following:
MyMainPrg (a Windows Forms Application)
MyFopWrapper (a Class Library that calls fop.dll)
But for my case this is not the solution, because in my target project, I have the following structure:
MainCmdLinePrg (a Console Application; calls DLL_1)
DLL_1 (calls DLLsharedFop) {there are several DLLs that can call DLLsharedFop}
DLLsharedFop (calls directly fop.dll; or - I don't care - might call MyFopWrapper)
Unfortunately this construct results in the error.
You can shorten to a pair (ACmdLinePrg,MyFopWrapper): already this does not work! But (MyMainPrg,MyFopWrapper) does...
Here is how I got that error and how I resolved:
My solultion looks like this:
ClientApp (references)--> ClassLibrary1
My ClassLibrary1 public functions are using, but not exposing any IKVM related objects, therefore the caller (ClientApp) did not have to add IKVM references. All is good in compile time.
However in runtime, the situation is different. I got the same exception and realized that ClientApp also needed to reference the correct IKVM dll (IKVM.OpenJDK.XML.Transform.dll) that contains "com.sun.org.apache.xalan.#internal.xsltc.trax" namespace.
I resolved a similar problem by adding the following before the problematic line:
var s = new com.sun.org.apache.xerces.#internal.jaxp.SAXParserFactoryImpl();
var t = new com.sun.org.apache.xalan.#internal.xsltc.trax.TransformerFactoryImpl();
As described here
Do you have the dll with the missing class in your working directory?
If you have the dll then it is a classloader problem. Look in the IKVM wiki. Often the BootClassPathAssemby help.
I was using NuGet Packages of FOP.dll v1.1.0 and IKVM pacakges of v7.1.45 in C#.NET app. I got this issue on Windows 2016 x64 server with error messages like:
------------------------------ Fop.cs (111): Provider com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
not found - at javax.xml.transform.TransformerFactory.newInstance()
Fop.cs (125): Provider
com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl not found
- at javax.xml.parsers.SAXParserFactory.newInstance()\r\n at org.apache.avalon.framework.configuration.DefaultConfigurationBuilder..ctor(Boolean
enableNamespaces)\r\n at
org.apache.avalon.framework.configuration.DefaultConfigurationBuilder..ctor()\r\n
I resolved the problem by adding those two lines at begins of procedure
com.sun.org.apache.xerces.#internal.jaxp.SAXParserFactoryImpl s = new com.sun.org.apache.xerces.#internal.jaxp.SAXParserFactoryImpl();
com.sun.org.apache.xalan.#internal.xsltc.trax.TransformerFactoryImpl t = new com.sun.org.apache.xalan.#internal.xsltc.trax.TransformerFactoryImpl();
helpful link:
https://github.com/KevM/tikaondotnet/issues/21
I want to make a plugin for Eclipse. The thing is that I looked into the API, and examples, and I managed to make a button on main bar, with a specific icon, and when I click it, open up an InputDialog.
The hard part, is that I want to start an aplication from this button, but not with Runtime as it was a new process. I simply want to start a class inside plugin, which will log in to a server and get some output from it. I want it to be opened in a console, like launching a normal application, or a separate console.
The best example of this kind is a Tomcat plugin which starts Tomcat, and then outputs the console to the Eclipse console. I want to do that too. I've looked at the Tomcat source plugin, but I got stuck there too. They use their own launcher.
I am not sure what you mean by "I want to simply start a class". I assume there is a command line tool that you want to execute and redirect its output to the console window.
To be able to do that without spawning a new process, you have to be able to control the output stream of the tool. If it cannot be controlled, then you have no choice but to start a new process to properly capture the tool's output.
It is technically possible to call System.setOut instead, but it will redirect output from all threads to your console which is not what you want.
Nevertheless you start by creating a console:
// function findConsole copied from:
// http://wiki.eclipse.org/FAQ_How_do_I_write_to_the_console_from_a_plug-in%3F
private MessageConsole findConsole(String name) {
ConsolePlugin plugin = ConsolePlugin.getDefault();
IConsoleManager conMan = plugin.getConsoleManager();
IConsole[] existing = conMan.getConsoles();
for (int i = 0; i < existing.length; i++)
if (name.equals(existing[i].getName()))
return (MessageConsole) existing[i];
//No console found, so create a new one.
MessageConsole myConsole = new MessageConsole(name, null);
conMan.addConsoles(new IConsole[]{myConsole});
return myConsole;
}
// Find my console
MessageConsole cons = findConsole("MyTool Console");
MessageConsoleStream out = cons.newMessageStream();
// Optionally get it's input stream so user can interact with my tool
IOConsoleInputStream in = cons.getInputStream();
// Optionally make a differently coloured error stream
MessageConsoleStream err = cons.newMessageStream();
err.setColor(display.getSystemColor(SWT.COLOR_RED));
// Display the console.
// Obtain the active page. See: http://wiki.eclipse.org/FAQ_How_do_I_find_the_active_workbench_page%3F
IWorkbenchPage page = ...;
String id = IConsoleConstants.ID_CONSOLE_VIEW;
IConsoleView view = (IConsoleView) page.showView(id);
view.display(cons);
Then set the input and output streams of my tool and start processing in a different thread so the UI will not block.
// Create my tool and redirect its output
final MyTool myTool = new MyTool();
myTool.setOutputStream(out);
myTool.setErrorStream(err);
myTool.setInputStream(in);
// Start it in another thread
Thread t = new Thread(new Runnable() {
public void run() {
myTool.startExecuting();
}
});
t.start();
If your tool does not support I/O redirection, you have no choice but to start it in another process with the ProcessBuilder and use a number of threads to move data between console and process streams See: Process.getInputStream(), Process.getOutputStream() and Process.getErrorStream().
The following links have additional useful details:
Executing a Java application in a separate process
FAQ How do I write to the console from a plug-in?
FAQ How do I find the active workbench page?
This is the code for running a new console with controls, like stop delete, and deleteAll! This is what I asked for in the beginning, but the message console is good to know!
ILaunchConfigurationType launchType = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType("org.eclipse.jdt.launching.localJavaApplication");
ILaunchConfigurationWorkingCopy config = null;
try {
config = launchType.newInstance(null, "My Plugin working");
} catch (CoreException e) {
System.err.println(e.getMessage());
}
config.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, "org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector");
String[] classpath = new String[] { "C:\\Users\\Administrator\\Documents\\myjr.jar" };
ArrayList classpathMementos = new ArrayList();
for (int i = 0; i < classpath.length; i++) {
IRuntimeClasspathEntry cpEntry = JavaRuntime.newArchiveRuntimeClasspathEntry(new Path(classpath[i]));
cpEntry.setClasspathProperty(IRuntimeClasspathEntry.USER_CLASSES);
try {
classpathMementos.add(cpEntry.getMemento());
} catch (CoreException e) {
System.err.println(e.getMessage());
}
}
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false);
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, classpathMementos);
config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, "collectorlog.handlers.MyClass");
try {
ILAUNCH = config.launch(ILaunchManager.RUN_MODE, null);
} catch (CoreException e) {
System.err.println(e.getMessage());
}
From a java application I run a bat file which starts another java application:
ProcessBuilder processBuilder = new ProcessBuilder("path to bat file");
Process process = processBuilder.start();
But the process never starts and no errors gets printed. But if I add the line:
String resultString = convertStreamToString(process.getInputStream());
after : Process process = processBuilder.start();
where:
public String convertStreamToString(InputStream is) throws IOException {
/*
* To convert the InputStream to String we use the Reader.read(char[]
* buffer) method. We iterate until the Reader return -1 which means there's
* no more data to read. We use the StringWriter class to produce the
* string.
*/
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
return writer.toString();
} else {
return "";
} }
it runs fine! Any ideas?
If it's really a batch file, you should run the command line interpreter as process (e.g. cmd.exe) with that file as parameter.
Solved here:
Starting a process with inherited stdin/stdout/stderr in Java 6
But, FYI, the deal is that sub-processes have a limited output buffer so if you don't read from it they hang waiting to write more IO. Your example in the original post correctly resolves this by continuing to read from the process's output stream so it doesn't hang.
The linked-to article demonstrates one method of reading from the streams. Key take-away concept though is you've got to keep reading output/error from the subprocess to keep it from hanging due to I/O blocking.