javaagent can not shut down when tomcat exits - javaagents

in javaagent start a Thread.
but tomcat exit ,javaagent can not shut down.
When the application exits, the JVM does not, because my agent is holding it up.
public MyTransformer(Instrumentation ins){
instrumentation = ins;
Thread thread = new TransformClassThread(ins);
thread.setDaemon(true);
thread.start();
}
run method in TransformClassThread
public void run() {
while (true){
try {
//do something
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
}

Related

How to implement exception handling around MefBootstrapper InitializeModules?

I have some Prism work. Specifically, a bootstrapper (MefBootstrapper) that calls InitializeModules. During one of the modules, an exception is raised, when I re-throw this, I get an exception unhandled.
Unsuccessfully, I have added delegate methods to the exception events, like:
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
System.Windows.Application.Current.DispatcherUnhandledException += CurrentOnDispatcherUnhandledException;
First, you need to mark the exception as handled in the event handler attached to AppDomain.CurrentDomain.UnhandledException to keep the application from crashing:
Application.Current.Dispatcher.UnhandledException += (sender, e) => e.Handled = true;
Second, an exception thrown during a given Prism Module initialization can stop other Modules from loading. To circumvent this you can subclass ModuleManager as follows:
public class ErrorHandlingModuleManager : ModuleManager
{
public ErrorHandlingModuleManager(IModuleInitializer moduleInitializer, IModuleCatalog moduleCatalog, ILoggerFacade loggerFacade) : base(moduleInitializer, moduleCatalog, loggerFacade)
{
}
protected override void LoadModulesThatAreReadyForLoad()
{
var initializationExceptions = new List<Exception>();
while (true)
{
try
{
base.LoadModulesThatAreReadyForLoad();
break;
}
catch (ModuleInitializeException e)
{
initializationExceptions.Add(e);
}
catch (Exception e)
{
initializationExceptions.Add(e);
break;
}
}
if (initializationExceptions.Any())
throw new AggregateException(initializationExceptions);
}
}
}
Be sure to register ErrorHandlingModuleManager with your Mef container to override the the default.

How to run different sql queries on different threads or as different processes using Java

I just want to know how can I run different SQL queries on separate threads or separate processes. Example:
If I send a SQL query (SQL1) from JDBC and if it takes a very long time to run, I should be able to send another SQL query (SQL2) which might take a smaller time to finish its execution. I want this query to run on a separate thread or a process so that it doesn't has to wait for the SQL1 to finish.
The MySQL JDBC driver (Connector/J) is thread save. So you can start two thread doing different things on the same database. Just start a different connection on each Thread. Take in mind, that a SQL Lock on thread1 could block thread2.
Simple example. Don't use the Old school Class.forName("com.mysql.jdbc.Driver"). JDBC4 will do that for you with the data from the connection URL. Main Thread will start both Threads and wait for both to finish. The two Threads are filled with dummy query.
public class TestThreads {
public static class Thread1 implements Runnable {
#Override
public void run() {
try {
Connection connection = DriverManager
.getConnection("jdbc:mysql://localhost/test?"
+ "user=myuser&password=mypassword");
Statement statment = connection.createStatement();
statment.executeQuery("select * from `table1`");
[...]
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static class Thread2 implements Runnable {
#Override
public void run() {
try {
Connection connection = DriverManager
.getConnection("jdbc:mysql://localhost/test?"
+ "user=myuser&password=mypassword");
Statement statment = connection.createStatement();
statment.executeQuery("select * from `table2`");
[...]
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread thread1 = new Thread(new Thread1());
Thread thread2 = new Thread(new Thread2());
thread1.start();
thread2.start();
try {
thread1.join(1000000);
thread2.join(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
If you want ResultSet then write create different threads for different query. Execute is a blocking process. So you have to create different threads for running different queries in the same process.

MySQL connection pooling with JERSEY

I'm developping a RESTful API with Jersey and MySQL.
I'm actually using the JDBC driver to connect to the database and I create a new connection everytime I want to acess it. As it clearly is a memory leakage, I started to implement the ServletContextClassclass but I don't know how to call the method when I need to get the result of a SQL query.
Here is how I did it wrong:
DbConnection.java
public class DbConnection {
public Connection getConnection() throws Exception {
try {
String connectionURL = "jdbc:mysql://root:port/path";
Connection connection = null;
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(connectionURL, "root", "password");
return connection;
}
catch (SQLException e) {
throw e;
}
}
}
DbData.java
public ArrayList<Product> getAllProducts(Connection connection) throws Exception {
ArrayList<Product> productList = new ArrayList<Product>();
try {
PreparedStatement ps = connection.prepareStatement("SELECT id, name FROM product");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Product product = new Product();
product.setId(rs.getInt("id"));
product.setName(rs.getString("name"));
productList.add(product);
}
return productList;
} catch (Exception e) {
throw e;
}
}
Resource.java
#GET
#Path("task/{taskId}")
#Consumes(MediaType.APPLICATION_JSON)
public Response getInfos(#PathParam("taskId") int taskId) throws Exception {
try {
DbConnection database= new DbConnection();
Connection connection = database.getConnection();
Task task = new Task();
DbData dbData = new DbData();
task = dbData.getTask(connection, taskId);
return Response.status(200).entity(task).build();
} catch (Exception e) {
throw e;
}
}
Here is where I ended up trying to implement the new class:
ServletContextClass.java
public class ServletContextClass implements ServletContextListener {
public Connection getConnection() throws Exception {
try {
String connectionURL = "jdbc:mysql://root:port/path";
Connection connection = null;
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(connectionURL, "root", "password");
return connection;
} catch (SQLException e) {
throw e;
}
}
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContextListener started");
DbConnection database = new DbConnection();
try {
Connection connection = database.getConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContextListener destroyed");
//con.close ();
}
}
But problem is, I don't know what to do next. Any help? Thanks
You need to set the Connection variable as an attribute of the ServletContext. Also, I would recommend using connection as a static class variable so you can close it in the contextDestroyed method.
You can retrieve the connection attribute in any of your servlets later on for doing your DB operations.
public class ServletContextClass implements ServletContextListener {
public static Connection connection;
public Connection getConnection(){
try {
String connectionURL = "jdbc:mysql://root:port/path";
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(connectionURL, "root", "password");
} catch (SQLException e) {
// Do something
}
}
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContextListener started");
getConnection();
arg0.getServletContext().setAttribute("connection", connection);
}
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContextListener destroyed");
try{
if(connection != null){
connection.close();
}
}catch(SQLException se){
// Do something
}
}
}
Finally access your connection attribute inside your Servlet (Resource). Make sure you pass #Context ServletContext to your Response method so you can access your context attributes.
#GET
#Path("task/{taskId}")
#Consumes(MediaType.APPLICATION_JSON)
public Response getInfos(#PathParam("taskId") int taskId, #Context ServletContext context) throws Exception {
try {
Connection connection = (Connection) context.getAttribute("connection");
Task task = new Task();
DbData dbData = new DbData();
task = dbData.getTask(connection, taskId);
return Response.status(200).entity(task).build();
} catch (Exception e) {
throw e;
}
}
Now that we have solved your current issue, we need to know what can go wrong with this approach.
Firstly, you are only creating one connection object which will be used everywhere. Imagine multiple users simultaneously accessing your API, the single connection will be shared among all of them which will slow down your response time.
Secondly, your connection to DB will die after sitting idle for a while (unless you configure MySql server not to kill idle connections which is not a good idea), and when you try to access it, you will get SQLExceptions thrown all over. This can be solved inside your servlet, you can check if your connection is dead, create it again, and then update the context attribute.
The best way to go about your Mysql Connection Pool will be to use a JNDI resource. You can create a pool of connections which will be managed by your servlet container. You can configure the pool to recreate connections if they go dead after sitting idle. If you are using Tomcat as your Servlet Container, you can check this short tutorial to get started with understanding the JNDI connection pool.

Application Exit unknowingly in Windows Phone

The application gets exit unknowingly with out catching the exception. We have implemented try catch functionality in the Application. I couldn't catch the exception in App unhandled exception.
For example, we have sub menu screen in our application, while clicking on the sub menu content listing screen is displayed. But some times continuously working on sub menu screen, the application gets exit with out unknowingly.
Kindly suggest.
Sub menu page sample code:
I have two stack panel and each having same set of codes for navigating to other pages.
private void stk_searchworkorder_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
try
{
(Application.Current.RootVisual as PhoneApplicationFrame).Navigate(new Uri("/MMS/WOSearch.xaml?History=false", UriKind.RelativeOrAbsolute));
}
catch (System.Reflection.TargetException ex) { } catch (Exception ex)
{
MessageBox.Show("Unknown exception", app.glbExceptionTitle, MessageBoxButton.OK);
}
}
private void stk_searchworkorder_MouseEnter(object sender, MouseEventArgs e)
{
try
{
SolidColorBrush br = new SolidColorBrush(Color.FromArgb(255, 40, 40, 40));
stk_searchworkorder.Background = br;
}
catch (System.Reflection.TargetException ex) { }
catch (Exception ex)
{
MessageBox.Show("Unknown exception", app.glbExceptionTitle, MessageBoxButton.OK);
}
}
private void stk_searchworkorder_MouseLeave(object sender, MouseEventArgs e)
{
try
{
SolidColorBrush br = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
stk_searchworkorder.Background = br;
}
catch (System.Reflection.TargetException ex) { }
catch (Exception ex)
{
MessageBox.Show("Unknown exception", app.glbExceptionTitle, MessageBoxButton.OK);
}
}
You are most likely running out of memory. The WP8 operating system WILL terminate your app, without your app being able to catch any exception, if your application's memory usage goes over its limit.
Limits are here
For troubleshooting, you can query your memory usage within your app using the DeviceExtendedProperties class. At the end of the day, you will want to make sure your app never goes over 150.
You application likely has a memory leak.
Look in your App.xaml.cs file. There is an Application_UnhandledException method. Make sure you do proper handling of exceptions in this method, and if you set e.Handled = true, it won't crash the application thereafter.
Note that this doesn't capture EVERY possible unhandled exception - for example, OutofMemoryException will still crash the app, but it does catch a lot of them.
Not sure if I'm missing something but wouldn't you just use NavigationService.Navigate instead of (Application.Current.RootVisual as PhoneApplicationFrame).Navigate?

jGit push produces exception

I am trying to use jGit in my java project. The version I am using is "2.0.0.201206130900-r" and my OS is Windows. everything worked fine until i tried to do a push:
public static void main(String[] args) {
File gitDir = new File("c:\\new-repo\\");
try {
String localPath = "c:\\new-repo\\";
Repository localRepo = new FileRepository(localPath + ".git");
localRepo.create();
Git git = new Git(localRepo);
git.add().addFilepattern("c:\\test.txt").call();
git.commit().setMessage("testcommit").call();
git.push().call();
localRepo.close();
} catch (IllegalStateException ise) {
System.out.println("The repository already exists!");
} catch (IOException ioe) {
System.out.println("Failed to create the repository!");
} catch (NoFilepatternException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (GitAPIException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
what i get is the following:
Exception in thread "main" java.lang.NoClassDefFoundError: com/jcraft/jsch/JSchException
at org.eclipse.jgit.transport.Transport.<clinit>(Transport.java:111)
at org.eclipse.jgit.api.PushCommand.call(PushCommand.java:141)
at Application.main(Application.java:76)
Caused by: java.lang.ClassNotFoundException: com.jcraft.jsch.JSchException
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
... 3 more
Can pls someone tell me what is wrong in my code?
It seems you are missing the jsch library which is needed for pushing over SSH. Add it to your classpath (add it to your pom if you're using Maven or add the jar to your classpath).