Cannot write to a closed TextWriter - textwriter

I have a error,
"Cannot write to a closed TextWriter."
Code:
public class Logs
{
static string File_Path= "";
static public FileStream fs;
static public StreamWriter sw;
public static void Initialize(string path)
{
File_Path = path;
fs = new FileStream(File_Path, FileMode.Append, FileAccess.Write);
sw = new StreamWriter(fs);
}
public static void info_log(string msg)
{
sw.WriteLine("{0} [INFO] : {1}",DateTime.Now.ToString(),msg);
sw.WriteLine(" ");
sw.Close();
sw.Flush();
}
public static void error_log(Exception ex)
{
sw.WriteLine("{0} [ERROR] : {1}", DateTime.Now.ToString(), ex.Message);
sw.WriteLine("StackTrace : {0}:", ex.StackTrace);
sw.WriteLine(" ");
sw.Close();
sw.Flush();
}
public static void warning_log(string msg)
{
sw.WriteLine("{0} [WARNING] : {1}", DateTime.Now.ToString(), msg);
sw.WriteLine(" ");
sw.Close();
sw.Flush();
}
}

Well, you are closing the StreamWriter, and THEN flushing it after each write. In other words, you close the stream and then try to write to it.
Typically you would want to initialize once and then use the logging methods. That would only need a sw.Flush() after writing. (So... remove that sw.Close() in each method).
However, if your application only logs messages under some very rare circumstances, you would initialize before each call (since that happens so rarely) and close after flushing. That would need a reorder of sw.Flush() and sw.Close().

Related

Reading OKIO stream twice

I am using OKHTTP for networking and currently get a charStream from response.charStream() which I then pass for GSON for parsing. Once parsed and inflated, I deflate the model again to save to disk using a stream. It seems like extra work to have to go from networkReader to Model to DiskWriter. Is it possible with OKIO to instead go from networkReader to JSONParser(reader) as well as networkReader to DiskWriter(reader). Basically I want to to be able to read from the network stream twice.
You can use a MirroredSource (taken from this gist).
public class MirroredSource {
private final Buffer buffer = new Buffer();
private final Source source;
private final AtomicBoolean sourceExhausted = new AtomicBoolean();
public MirroredSource(final Source source) {
this.source = source;
}
public Source original() {
return new okio.Source() {
#Override
public long read(final Buffer sink, final long byteCount) throws IOException {
final long bytesRead = source.read(sink, byteCount);
if (bytesRead > 0) {
synchronized (buffer) {
sink.copyTo(buffer, sink.size() - bytesRead, bytesRead);
// Notfiy the mirror to continue
buffer.notify();
}
} else {
sourceExhausted.set(true);
}
return bytesRead;
}
#Override
public Timeout timeout() {
return source.timeout();
}
#Override
public void close() throws IOException {
source.close();
sourceExhausted.set(true);
synchronized (buffer) {
buffer.notify();
}
}
};
}
public Source mirror() {
return new okio.Source() {
#Override
public long read(final Buffer sink, final long byteCount) throws IOException {
synchronized (buffer) {
while (!sourceExhausted.get()) {
// only need to synchronise on reads when the source is not exhausted.
if (buffer.request(byteCount)) {
return buffer.read(sink, byteCount);
} else {
try {
buffer.wait();
} catch (final InterruptedException e) {
//No op
}
}
}
}
return buffer.read(sink, byteCount);
}
#Override
public Timeout timeout() {
return new Timeout();
}
#Override
public void close() throws IOException { /* not used */ }
};
}
}
Usage would look like:
MirroredSource mirroredSource = new MirroredSource(response.body().source()); //Or however you're getting your original source
Source originalSource = mirroredSource.original();
Source secondSource = mirroredSource.mirror();
doParsing(originalSource);
writeToDisk(secondSource);
originalSource.close();
If you want something more robust you can repurpose Relay from OkHttp.

Freemarker removeIntrospectionInfo does not work with DCEVM after model hotswap

I am using Freemarker and DCEVM+HotSwapManager agent. This basically allows me to hotswap classes even when adding/removing methods.
Everything works like charm until Freemarker uses hotswapped class as model. It's throwing freemarker.ext.beans.InvalidPropertyException: No such bean property on me even though reflection shows that the method is there (checked during debug session).
I am using
final Method clearInfoMethod = beanWrapper.getClass().getDeclaredMethod("removeIntrospectionInfo", Class.class);
clearInfoMethod.setAccessible(true);
clearInfoMethod.invoke(clazz);
to clear the cache, but it does not work. I even tried to obtain classCache member field and clear it using reflection but it does not work too.
What am I doing wrong?
I just need to force freemarker to throw away any introspection on model class/classes he has already obtained.
Is there any way?
UPDATE
Example code
Application.java
// Application.java
public class Application
{
public static final String TEMPLATE_PATH = "TemplatePath";
public static final String DEFAULT_TEMPLATE_PATH = "./";
private static Application INSTANCE;
private Configuration freemarkerConfiguration;
private BeansWrapper beanWrapper;
public static void main(String[] args)
{
final Application application = new Application();
INSTANCE = application;
try
{
application.run(args);
}
catch (InterruptedException e)
{
System.out.println("Exiting");
}
catch (IOException e)
{
System.out.println("IO Error");
e.printStackTrace();
}
}
public Configuration getFreemarkerConfiguration()
{
return freemarkerConfiguration;
}
public static Application getInstance()
{
return INSTANCE;
}
private void run(String[] args) throws InterruptedException, IOException
{
final String templatePath = System.getProperty(TEMPLATE_PATH) != null
? System.getProperty(TEMPLATE_PATH)
: DEFAULT_TEMPLATE_PATH;
final Configuration configuration = new Configuration();
freemarkerConfiguration = configuration;
beanWrapper = new BeansWrapper();
beanWrapper.setUseCache(false);
configuration.setObjectWrapper(beanWrapper);
try
{
final File templateDir = new File(templatePath);
configuration.setTemplateLoader(new FileTemplateLoader(templateDir));
}
catch (IOException e)
{
throw new RuntimeException(e);
}
final RunnerImpl runner = new RunnerImpl();
try
{
runner.run(args);
}
catch (RuntimeException e)
{
e.printStackTrace();
}
}
public BeansWrapper getBeanWrapper()
{
return beanWrapper;
}
}
RunnerImpl.java
// RunnerImpl.java
public class RunnerImpl implements Runner
{
#Override
public void run(String[] args) throws InterruptedException
{
long counter = 0;
while(true)
{
++counter;
System.out.printf("Run %d\n", counter);
// Application.getInstance().getFreemarkerConfiguration().setObjectWrapper(new BeansWrapper());
Application.getInstance().getBeanWrapper().clearClassIntrospecitonCache();
final Worker worker = new Worker();
worker.doWork();
Thread.sleep(1000);
}
}
Worker.java
// Worker.java
public class Worker
{
void doWork()
{
final Application application = Application.getInstance();
final Configuration freemarkerConfiguration = application.getFreemarkerConfiguration();
try
{
final Template template = freemarkerConfiguration.getTemplate("test.ftl");
final Model model = new Model();
final PrintWriter printWriter = new PrintWriter(System.out);
printObjectInto(model);
System.out.println("-----TEMPLATE MACRO PROCESSING-----");
template.process(model, printWriter);
System.out.println();
System.out.println("-----END OF PROCESSING------");
System.out.println();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (TemplateException e)
{
e.printStackTrace();
}
}
private void printObjectInto(Object o)
{
final Class<?> aClass = o.getClass();
final Method[] methods = aClass.getDeclaredMethods();
for (final Method method : methods)
{
System.out.println(String.format("Method name: %s, public: %s", method.getName(), Modifier.isPublic(method.getModifiers())));
}
}
}
Model.java
// Model.java
public class Model
{
public String getMessage()
{
return "Hello";
}
public String getAnotherMessage()
{
return "Hello World!";
}
}
This example does not work at all. Even changing BeansWrapper during runtime won't have any effect.
BeansWrapper (and DefaultObjectWrapper's, etc.) introspection cache relies on java.beans.Introspector.getBeanInfo(aClass), not on reflection. (That's because it treats objects as JavaBeans.) java.beans.Introspector has its own internal cache, so it can return stale information, and in that case BeansWrapper will just recreate its own class introspection data based on that stale information. As of java.beans.Introspector's caching, it's in fact correct, as it builds on the assumption that classes in Java are immutable. If something breaks that basic rule, it should ensure that java.beans.Introspector's cache is cleared (and many other caches...), or else it's not just FreeMarker that will break. At JRebel for example they made a lot of effort to clear all kind of caches. I guess DCEVM doesn't have the resources for that. So then, it seems you have to call Introspector.flushCaches() yourself.
Update: For a while (Java 7, maybe 6) java.beans.Introspector has one cache per thread group, so you have call flushCaches() from all thread groups. And this all is actually implementation detail that, in principle, can change any time. And sadly, the JavaDoc of Introspector.flushCaches() doesn't warn you...

How to capture MVXTrace in error reporting tool

I'm using MvvmCross and playing around with some ways to get the MvxTrace in my reporting tool. In this case I'm using Raygun. Raygun gives me the option of including additional messages to the error message that I want to throw, which is what I'm thinking I have to use to get this to happen. Basically I want to do something like this in the code:
var client = new RaygunClient();
var tags = new List<string> { "myTag" };
var customData = new Dictionary<int, string>() { {1, "**MVXTrace stuff here**"} };
client.Send(exception, tags, customData);
How can I hook this up? I'm getting confused when I'm looking at the Trace setup. I'm assuming I need to do something with my DebugTrace file that I'm using to inject. Right now it looks like this:
public class DebugTrace : IMvxTrace
{
public void Trace(MvxTraceLevel level, string tag, Func<string> message)
{
Debug.WriteLine(tag + ":" + level + ":" + message());
}
public void Trace(MvxTraceLevel level, string tag, string message)
{
Debug.WriteLine(tag + ":" + level + ":" + message);
}
public void Trace(MvxTraceLevel level, string tag, string message, params object[] args)
{
try
{
Debug.WriteLine(string.Format(tag + ":" + level + ":" + message, args));
}
catch (FormatException)
{
Trace(MvxTraceLevel.Error, tag, "Exception during trace of {0} {1} {2}", level, message);
}
}
}
Can I do something that hooks into the IMvxTrace logic to attach inner exceptions and etc to my RaygunClient? It's hard for me to see what is causing specific errors because if I leave it the way it is I get errors that look like this:
[MvxException: Failed to construct and initialize ViewModel for type MyProject.Core.ViewModels.SignatureViewModel from locator MvxDefaultViewModelLocator - check MvxTrace for more information]
Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel(Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState, IMvxViewModelLocator viewModelLocator):0
Cirrious.MvvmCross.ViewModels.MvxViewModelLoader.LoadViewModel(Cirrious.MvvmCross.ViewModels.MvxViewModelRequest request, IMvxBundle savedState):0
Cirrious.MvvmCross.Droid.Views.MvxAndroidViewsContainer.ViewModelFromRequest(Cirrious.MvvmCross.ViewModels.MvxViewModelRequest viewModelRequest, IMvxBundle savedState):0
Cirrious.MvvmCross.Droid.Views.MvxAndroidViewsContainer.CreateViewModelFromIntent(Android.Content.Intent intent, IMvxBundle savedState):0
Cirrious.MvvmCross.Droid.Views.MvxAndroidViewsContainer.Load(Android.Content.Intent intent, IMvxBundle savedState, System.Type viewModelTypeHint):0
Cirrious.MvvmCross.Droid.Views.MvxActivityViewExtensions.LoadViewModel(IMvxAndroidView androidView, IMvxBundle savedState):0
Cirrious.MvvmCross.Droid.Views.MvxActivityViewExtensions+<>c__DisplayClass3.<OnViewCreate>b__1():0
Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate(IMvxView view, System.Func`1 viewModelLoader):0
Cirrious.MvvmCross.Droid.Views.MvxActivityViewExtensions.OnViewCreate(IMvxAndroidView androidView, Android.OS.Bundle bundle):0
Cirrious.MvvmCross.Droid.Views.MvxActivityAdapter.EventSourceOnCreateCalled(System.Object sender, Cirrious.CrossCore.Core.MvxValueEventArgs`1 eventArgs):0
(wrapper delegate-invoke) System.EventHandler`1<Cirrious.CrossCore.Core.MvxValueEventArgs`1<Android.OS.Bundle>>:invoke_void__this___object_TEventArgs (object,Cirrious.CrossCore.Core.MvxValueEventArgs`1<Android.OS.Bundle>)
Cirrious.CrossCore.Core.MvxDelegateExtensionMethods.Raise[Bundle](System.EventHandler`1 eventHandler, System.Object sender, Android.OS.Bundle value):0
Cirrious.CrossCore.Droid.Views.MvxEventSourceActivity.OnCreate(Android.OS.Bundle bundle):0
MyProject.Droid.Views.SignatureView.OnCreate(Android.OS.Bundle bundle):0
Android.App.Activity.n_OnCreate_Landroid_os_Bundle_(IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState):0
(wrapper dynamic-method) object:3af7783d-a44d-471c-84a6-662ebfaea4ae (intptr,intptr,intptr)
It would be really helpful, as that message suggests, if I could get the MvxTrace with it to track down exactly why initializing this ViewModel failed. Any suggestions?
This is how I do it on Android. I use the Android.Util.Log class. This will then log the messages to the Android Device Log.
public class DebugTrace : IMvxTrace
{
public void Trace(MvxTraceLevel level, string tag, Func<string> message)
{
Trace(level, tag, message());
}
public void Trace(MvxTraceLevel level, string tag, string message)
{
switch (level)
{
case MvxTraceLevel.Diagnostic:
Log.Debug(tag, message);
break;
case MvxTraceLevel.Warning:
Log.Warn(tag, message);
break;
case MvxTraceLevel.Error:
Log.Error(tag, message);
break;
default:
Log.Info(tag, message);
break;
}
}
public void Trace(MvxTraceLevel level, string tag, string message, params object[] args)
{
try
{
Trace(level, tag, string.Format(message, args));
}
catch (FormatException)
{
Trace(MvxTraceLevel.Error, tag, "Exception during trace of {0} {1}", level, message);
}
}
}
You can then get the log using the following:
public class AndroidLogReader
{
public string ReadLog(string tag)
{
var cmd = "logcat -d";
if (!string.IsNullOrEmpty(tag)) cmd += " -s " + tag;
var process = Java.Lang.Runtime.GetRuntime().Exec(cmd);
using (var sr = new StreamReader(process.InputStream))
{
return sr.ReadToEnd();
}
}
}
Here is what I did to get this to work for me:
I have a BaseView that I'm using for all of my Android activities. I make use of this BaseView to hook up and log Unhandled Exceptions like so:
public abstract class BaseView : MvxActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;
AndroidEnvironment.UnhandledExceptionRaiser += HandleAndroidException;
}
protected void HandleUnhandledException(object sender, UnhandledExceptionEventArgs args)
{
var e = (Exception)args.ExceptionObject;
Mvx.Trace(MvxTraceLevel.Error, "Exception: {0}", e.ToLongString());
var logReader = new AndroidLogReader();
var logMessages = logReader.ReadLog("mvx:E");
var customData = new Dictionary<string, string> { { "logMessage", logMessages } };
var session = SessionController.Instance;
var user = new RaygunIdentifierMessage(session.UserName + " " + session.Company);
var rayMessage = RaygunMessageBuilder.New
.SetEnvironmentDetails()
.SetMachineName(Environment.MachineName)
.SetClientDetails()
.SetExceptionDetails(e)
.SetUser(user)
.SetUserCustomData(customData)
.Build();
RaygunClient.Current.Send(rayMessage);
}
protected void HandleAndroidException(object sender, RaiseThrowableEventArgs e)
{
var exception = e.Exception;
Mvx.Trace(MvxTraceLevel.Error, "Exception: {0}", e.Exception.ToLongString());
var logReader = new AndroidLogReader();
var logMessages = logReader.ReadLog("mvx:E");
var customData = new Dictionary<string, string> { { "logMessage", logMessages } };
var session = SessionController.Instance;
var user = new RaygunIdentifierMessage(session.UserName + " " + session.Company);
var rayMessage = RaygunMessageBuilder.New
.SetEnvironmentDetails()
.SetMachineName(Environment.MachineName)
.SetClientDetails()
.SetExceptionDetails(exception)
.SetUser(user)
.SetUserCustomData(customData)
.Build();
RaygunClient.Current.Send(rayMessage);
}
}
My DebugTrace.cs looks like so:
public class DebugTrace : IMvxTrace
{
public void Trace(MvxTraceLevel level, string tag, Func<string> message)
{
Trace(level, tag, message());
}
public void Trace(MvxTraceLevel level, string tag, string message)
{
switch (level)
{
case MvxTraceLevel.Diagnostic:
Log.Debug(tag, message);
break;
case MvxTraceLevel.Warning:
Log.Warn(tag, message);
break;
case MvxTraceLevel.Error:
Log.Error(tag, message);
break;
default:
Log.Info(tag, message);
break;
}
}
public void Trace(MvxTraceLevel level, string tag, string message, params object[] args)
{
try
{
Trace(level, tag, string.Format(message, args));
}
catch (FormatException)
{
Trace(MvxTraceLevel.Error, tag, "Exception during trace of {0} {1} {2}", level, message);
}
}
}
And my AndroidLogReader looks like so:
public class AndroidLogReader
{
public string ReadLog(string tag)
{
var cmd = "logcat -d";
if (!string.IsNullOrEmpty(tag))
{
cmd += " -s " + tag;
}
var process = Java.Lang.Runtime.GetRuntime().Exec(cmd);
using (var sr = new StreamReader(process.InputStream))
{
return sr.ReadToEnd();
}
}
}
With these things in place I now get custom data attached to all of my Raygun errors that includes the stack trace for all errors from Mvx. Thank you so much #Kiliman for pointing me towards the building blocks to get this to work!

java null pointer from another class

I have 2 classes one called Gui and one called Listener.
The code for Listener is :
package app.assignment.u0961036.core;
import net.jini.space.JavaSpace;
public class Listener extends Thread {
private JavaSpace space;
private Gui list;
public void run() {
space = SpaceUtils.getSpace("localhost");
System.out.println("In Listener");
int i = 0;
while(true){
i++;
try{
Message mTemplate = new Message();
System.out.println("Listner: template created");
Message nextMessage = (Message)space.take(mTemplate,null,Long.MAX_VALUE);
System.out.println("Listner: Message created");
String message = nextMessage.message;
System.out.println("Listner: message= "+message);
list.newMessage(message);
} catch ( Exception e) {
e.printStackTrace();
}
if(i % 10 == 0){
System.out.println("I = "+i);
}
}
}
public static void listen() {
(new Listener()).start();
}
The relevant code in Gui is:
public void newMessage(String message){
System.out.println("in new message");
chatTextArea.append(" Someone Says: " + message + "\n" );
}
When The code in Listener is run I get a null pointer from the following line:
list.newMessage(message);
I'm not sure why because the object is created.
The GUI is also created win the Gui class if you haven't already guessed.
any Ideas?
package app.assignment.u0961036.core;
import net.jini.space.JavaSpace;
public class Listener extends Thread {
private JavaSpace space;
space = new JavaSpace();
private Gui list;
list = new Gui();
public void run() {
space = SpaceUtils.getSpace("localhost");
System.out.println("In Listener");
int i = 0;
while(true){
i++;
try{
Message mTemplate = new Message();
System.out.println("Listner: template created");
Message nextMessage = (Message)space.take(mTemplate,null,Long.MAX_VALUE);
System.out.println("Listner: Message created");
String message = nextMessage.message;
System.out.println("Listner: message= "+message);
list.newMessage(message);
} catch ( Exception e) {
e.printStackTrace();
}
if(i % 10 == 0){
System.out.println("I = "+i);
}
}
}
public static void listen() {
(new Listener()).start();
}
The code above should fix your problem I think. In Java you create Objects by declaring and instantiating and initialising them. Read here for more information.

How do I get to load image in J2ME?

I am using TimerTask and ImageLoader class to load n image to an image item.
public class Imageloader implements Runnable{
private ImageItem item=null;
private String url=null;
/*
* initializes the imageItem
*/
public Imageloader(ImageItem item,String url){
this.item=item;
this.url=url;
}
private Image getImage(String url) throws IOException {
item.setLabel(item.getLabel()+12);
System.out.println("Test 5");
HttpConnection connection = null;
DataInputStream inp = null;
int length;
byte[] data;
try {System.out.println("Test 6");
connection = (HttpConnection) Connector.open(url);
item.setLabel(item.getLabel()+13);
connection.getResponseMessage();
System.out.println("Test 7");
length = (int) connection.getLength();
item.setLabel(item.getLabel()+14);
System.out.println("Length is "+length);
System.out.println("Test 8");
data = new byte[length];
inp = new DataInputStream(connection.openInputStream());
item.setLabel(item.getLabel()+15);
System.out.println("Test 9");
inp.readFully(data);
item.setLabel(item.getLabel()+16);
System.out.println("Test 10");
return Image.createImage(data, 0, data.length);
}
finally {
if (connection != null) connection.close();
if (inp != null)inp.close();
}
}
public void run() {
System.out.println("Test 1");
Image image=null;
try{
if (url!=null){
System.out.println("Test 2");
image=getImage(url);
System.out.println("Test 3");
item.setImage(image);
item.setLabel(item.getLabel()+17);
System.out.println("Test 4");
}
else{
item.setAltText("Map address specified is incorrect");
}
}
catch(IOException e){
item.setAltText("Map cannot be loaded now");
}
}
}
public class MapTimer extends TimerTask{
DatagramConnection connection=null;
String message=null;
Imageloader imageretriever;
ImageItem item=null;
MapTimer (DatagramConnection connection,String message,ImageItem Img_map ){
this.connection=connection;
this.message=message;
this.item=Img_map;
item.setLabel(item.getLabel()+1);
System.out.println("Map is initizlized...");
}
public void run() {
System.out.println("Map starting...");
item.setLabel(item.getLabel()+2);
String serverquery=null;
try {
item.setLabel(item.getLabel()+3);
sendMessage(message);
item.setLabel(item.getLabel()+4);
//serverquery=receiveMessage() ;
item.setLabel(item.getLabel()+5);
//item.setLabel(" Loading...." );
//formatmessage(serverquery);
String url="http://maps.google.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=14&size=512x512&maptype=roadmap"+
"&markers=color:blue|label:S|40.702147,-74.015794&markers=color:green|label:G|40.711614,-74.012318"+
"&markers=color:red|color:red|label:C|40.718217,-73.998284&sensor=false";
Imageloader Im=new Imageloader(item,url);
item.setLabel(item.getLabel()+6);
(new Thread(Im)).start();
item.setLabel(item.getLabel()+7);
System.out.println("server map query is::: "+serverquery);
} catch (IOException ex) {
System.out.println("Error2"+ex);
}
catch(Exception e){
System.out.println("Error3"+e);
}
}
/*
* Sends a message via UDP to server
*/
private void sendMessage(String message) throws IOException{
Datagram packet_send=null;
if (connection != null){
byte[] packetsenddata=message.getBytes();
packet_send = connection.newDatagram(packetsenddata,packetsenddata.length);
connection.send(packet_send);
packet_send = null;
}
}
}
This is how I set the Timer;
MapTimer maptimer=new MapTimer (connection,mapquery ,Img_map );
Timer timer=new Timer();
timer.schedule(maptimer, 5000, 100000);
It's working fine with the enulator but as I deploy it on my mob,the image is not loading..
The image label is somewhat like Stopping 234567234567 which implies that my timer is running fine. It is not entering the ImageLoader class... How do get to load this image?
This is difficult to say without further debuggind. I recommend you to use Micrologger + a web server, in order to debug your midlets on the device.
Looking to your code, I suspect of this line length = (int) connection.getLength();. Could it fail on Nokia's IO library implementation?

Resources