I have a particularly tricky situation here. I am supporting an java based packaged web application that runs on JBoss. The application is a packaged application so I don't really have access to any code or know how the code was developed.
What I am trying to find out is what the JDBC fetchSize is being set to. I don't know where it is being set, meaning at the ResultSet level or Statement level etc..
Here is what I have tried so far:
1) I tried to configure tracing for the JDBC driver by downloading the ojdbc_g.jar file from Oracle and following the instructions that they provided. Unfortunately, in those instructions, it states that I need to add this jar file to the CLASSPATH and I am not sure where that is being set in this application. Needless to say, this path was not fruitful, as I was never able to successfully get a trace file output.
2) I tried using WireShark to capture all TNS packets to see if I could find it out that way, and this again was fruitless because at that level, it is next to impossible to actually find how many rows are being passed each time. There are so many other dependencies there, and I was unable to get the info I am after.
3) The last thing I tried was configuring a database side trace of SQL Net calls to the database, but I am not sure whether I have to do this in the sqlnet.ora file or if I have to trace the listener.
This is where I am stuck now. Again, all I want to do is find out what the application's JDBC fetchSize is being set (if its even being set at all). I know that this can impact the performance of the application so that's why I want to find it.
Any guidance is appreciated.
Thanks.
unpack the jar file, try grepping for fetchSize in the class files, this will give you the class file. Then disassemble or decompile, or debug to see what it is set to.
Related
I'm trying to write logs of multiple services to same file, but my rolling policy given is not working, tried with both time based and size based rollings. Thing is my services are running simultanously and writting there logs to same file in my local directory. When tried to write logs by single service it is working as expected.
Please help me to solve this issue tried with different rolling policies.
Appender to log to file
${LOG_FILE}
Minimum logging level to be presented in the console logs
INFO
${LOG_PATH}/archived/log_%d{dd-MM-yyyy}_%i.log
10KB
I had an experience similar to yours with Log4j 1.x then I debugged an appender back then (~5-6 years ago) and came to the following conclusions:
I don't think you can write data from multiple services into the same file. In other words,
Logging framework usually assumes that only it can change the file. In some Operating Systems (windows) it will even stop writing into file if some other process will rename / change the current file.
Of course its just a code and you could create a more sophisticated appeneder that will probable make it work, but frankly I don't think it worth the effort.
So I suggest writing into different files, where file name can be generated in a way that it will contain a pid of the resource. The downside of this method is that if the process dies and then re-runs, on-one will take care of the old resources.
Another approach (somewhat similar) - is to create a folder with logs for each service so that they'll get different logs based on folder (even if files in these folders will be with the same name).
I am migrating a legacy project to a new server. Previously the project used a Oracle DB but now i want it to use Postgress. The queries are simple enough and work the same in Postgres.
However the project is missing a Postgres jdbc-driver. Can i somehow add this dependency sideways to the jar without recompiling?
Can i somehow add this dependency to the jar without recompiling?
It depends.
If you are running the server as java -jar myserver.jar ..., then you will at least need to modify the manifest in the JAR file. Strictly speaking this doesn't entail recompiling, but you do need to explode, modify and repack the JAR file.
If the server uses Class.forName to explicitly load an Oracle Driver class, then you will need to change that code to load the Postgres Driver class instead. (There are other ways to use JDBC that avoid this, but this depends on how your legacy server is implemented.)
If your server uses Oracle specific database classes, or Oracle specific SQL features (or it needs to do the same in the Postgres world) then more extensive changes will be required.
But without actually examining your codebase in detail, we can't predict what is required.
My advice is to replace the Oracle driver JAR with a Postgres driver JAR, and see what happens when you run your server against a Postgres database with the appropriate schemas and data.
But I wouldn't do this "in production". Do it in a test environment. If you can't set up a suitable test environment ... forget it.
And if you don't have the source code for your server, I would forget it too. If anything goes wrong you will most likely need source code to figure out the problem and fix it.
I've been messing around with Apache Derby inside Eclipse. I've booted up a Network Server, and I've been working with servlets. In my Eclipse project, I have a class called "User", inside the package "base.pack". I have an SQL script open, and I've been trying to convert User, which implements Serializable, into a custom type. When I run the following lines, everything works fine:
CREATE TYPE CARTEBLANCHE.bee
EXTERNAL NAME 'base.pack.User'
LANGUAGE JAVA
This follows the general format they identify here: http://db.apache.org/derby/docs/10.7/ref/rrefsqljcreatetype.html#rrefsqljcreatetype
Now, when I try to create a table using this new type, I get an error. I run the following line:
CREATE TABLE CARTEBLANCHE.TestTabel (ID INTEGER NOT NULL, NAME CARTEBLANCHE.bee, PRIMARY KEY(ID));
And I receive the following error:
The class 'base.pack.User' for column 'NAME' does not exist or is inaccessible. This can happen if the class is not public.
Now, the class is in fact public, and as I noted before, it does implement Serializable. I don't think I'm stating the package name incorrectly, but I could be wrong. I'm wondering, is this an issue with my classpath? If so, how would you suggest I fix this? I admit that I do not know much about the classpath.
Thank you.
(For reference, I have configured my project build path to include derby.jar, derbyclient.jar, derbytools.jar, and derbynet.jar, and I have put these files into my project's lib folder as well).
As politely as I can, may I suggest that if you are uncomfortable with Java's CLASSPATH notion, then writing your own custom data types in Derby is likely to be a challenging project?
In the specific case you describe here, one issue that will arise is that your custom Java code has to be available not only to your client application, but also to the Derby Network Server, which means you will need to be modifying the server's CLASSPATH as well as your application's CLASSPATH.
It's all possible, it's just not a beginner-level project.
To get started with customizing your Derby Network Server, the first topic involves how you are starting it. Here's an overview of the general process: http://db.apache.org/derby/docs/10.11/adminguide/tadmincbdjhhfd.html
Depending on how precisely you are starting the Derby Network Server, you'll possibly be editing the CLASSPATH settting in the startNetworkServer or startNetworkServer.bat script, or you'll be editing the CLASSPATH setting in your own script that you have written to start the server.
If it's a tool like Eclipse or Netbeans which is starting the Derby Network Server, you'll need to dig into the details of that tool to learn more about how to configure its CLASSPATH.
And if you've written a custom Java application to start the Derby Network Server (e.g., as described here: http://db.apache.org/derby/docs/10.11/adminguide/tadminconfig814963.html) then you'd be configuring the CLASSPATH of your custom application.
Regardless, as a basic step, you're going to want to be deploying your custom Java extension classes in the Derby Network Server's classpath, which means you'll want to build them into a .jar file and put that .jar file somewhere that the Derby Network Server has access to, and you'll want to make that build-a-jar-and-copy-it-to-the-right-location process straightforward, so you should integrate it into whatever build tool you're using (Apache Ant?).
And, you'll need to consider Java security policy, because the default security policy will prevent you from trivially loading custom Java classes into your Derby Network Server as that would seem like a malware attack and the Derby Network Server is going to try to prevent that. So study this section of the Security manual: http://db.apache.org/derby/docs/10.11/security/tsecnetservrun.html
We have used liquibase at our company for a while, and we've had a continuous integration environment set up for the database migrations that would break a job when a patch had an error.
An interesting "feature" of that CI environment is that the breakage had a "likely culprit", because all patches need to have an "author", and the error message shows the author name.
If you don't know what liquibase is, that's ok, its not the point.
The point is: having a person name attached to a error is really good to the software development proccess: problems get addressed way faster.
So I was thinking: Is that possible for Java stacktraces?
Could we possibly had a stacktrace with peoples names along with line numbers like the one below?
java.lang.NullPointerException
at org.hibernate.tuple.AbstractEntityTuplizer.createProxy(AbstractEntityTuplizer.java:372:john)
at org.hibernate.persister.entity.AbstractEntityPersister.createProxy(AbstractEntityPersister.java:3121:mike)
at org.hibernate.event.def.DefaultLoadEventListener.createProxyIfNecessary(DefaultLoadEventListener.java:232:bob)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:173:bob)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:87:bob)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:862:john)
That kind of information would have to be pulled out from a SCM system (like performing "svn blame" for each source file).
Now, forget about trashing the compilation time for a minute: Would that be even possible?
To add metadata to class files like that?
In principle you can add custom information to .class files (there's and attribute section where you can add stuff). You will have to write your own compiler/compiler extension to do so. There is no way to add something to your source code that then will show up in the class file.
You will also have major problems in practice:
The way stack-traces a built/printed is not aware of anything you add to the class file. So if you want this stuff printed like you show above, you have to hack some core JDK classes.
How much detail do you want? The last person who committed any change to a given file? That's not precise enough in practice, unless files are owned by a single developer.
Adding "last-committed-by" information at a finer granularity, say per method, or even worse, per line will quickly bloat your class file (and class files are limited in size to 64K)
As a side note, whether or not blaming people for bugs helps getting bugs fixed faster strongly depends on the culture of the development organization. Make sure you work in one where this helps before you spend a lot of time developing something like this.
Normally such feature can be implemented on top of the version control system. You need to know revision of your file in your version control system, then you can call blame/annotate command to get information on who has changed each individual line. You don't need to store this info into the class file, as long as you can identify revision of each class you deploy (e.g. you only deploy certain tag or label).
If you don't want to go into the version control when investigating stack trace, you could store line annotation info into the class file, e.g. using class post processor during your build that can add a custom annotation at the class level (this is relatively trivial to implement using ASM). Then logger that prints stack trace could read this annotation at runtime, similarly to showing jar versions.
One way to add add custom information to your class files using annotations in the source code. I don't know how you would put that information reliably in the stack trace, but you could create a tool to retrieve it.
As #theglauber correctly pointed out , you can use annotations to add custom metadata. Althougth i am not really sure you if you cant retrieve that information from your database implementing beans and decorating your custom exceptions manager.
I am trying to configure a custom layout class to Log4J as described in my previous post. The class uses java.util.regex.Matcher to identify potential credit card numbers in log messages. It works perfectly in unit tests, also in a minimal web app containing a single servlet. However when I try to deploy it with our app in JBoss, I get the following error:
--- MBEANS THAT ARE THE ROOT CAUSE OF THE PROBLEM ---
ObjectName: jboss.web.deployment:war=MyWebApp-2010_02-SNAPSHOT.war,id=476602902
State: FAILED
Reason: java.lang.LinkageError: java/util/regex/Matcher
I couldn't even find any info on this form of the error - typically LinkageError seems to show up with a "loader constrain violation" message, like in here.
Technical details: we use JBoss 4.2, Java 5, Log4J 1.2.12. We deploy our app in an .ear, which contains (among others) the above mentioned .war file, and the custom layout class in a separate jar file (let's call it Commons). We override the default settings in jboss-log4j.xml with our own log4j.properties located in a different folder, which is added to the classpath at startup, and is provided via Sapient's Carbon framework.
Update to #skaffman's answer:
The reason we have a separate log4j.properties file is the scheme propagated by Sapient Carbon. This basically decouples the configuration and data files from the application server environment, so that they are accessible via Carbon's lookup functionality and they can be stored in a directory external to the app server. We inherited this setup, and we hate it because it causes us lots of trouble with deployment, classpath issues etc. since it does not adhere to the JEE conventions. We aim to get rid of it in the long run, but it's gonna take time :-(
Even though the separate log4j.properties file is not best practice, it certainly works. It has been functioning in our app for years, and I could also make it work with a minimalist web app containing a single servlet (not using Sapient Carbon). If log4j.properties is put into the classpath, Log4J reads it properly when the web app is launched, and reconfigures logging accordingly.
Update#2: An interesting finding is that Matcher is not even used in MyWebApp, only in the Commons module (and another module, in a separate jar). In Commons, it has been used before, in a class called StringHelper, which is used indirectly by MyWebApp, via other modules.
I guess this rules out the possibility of two different Matcher class versions loaded by different classloaders. So my only remaining guess is that Matcher is loaded by two different classloaders when it is used from the jar and the war, and then attempted to pass from one to the other. This is explained by Frank Kieviet's excellent article. However, I believe that such a setup would cause a "loader constraint violation" rather than this form of the error.
Update#3: If I add this appender (example 3.8) to jboss-log4j.xml, the error disappears, and the server runs perfectly :-o This obviously has to do something with loading log4j.jar, because this setup requires the jar to be present in the server lib directory. It works also if I change the appender type to org.jboss.logging.appender.FileAppender, and set log level to WARN, which results in an empty ucl.log file. This may suit as a temporary workaround, but I am still eager to fully understand what's going on here.
What does this error message mean, and how can I fix it properly?
Epilogue
After a long wait, I finally got to eliminate Carbon from the logging process and migrate our logging config into server/conf/jboss-log4j.xml. This required that I publish our custom log filter class in a separate jar in the server/lib directory. After this, the class loading works again, without the workaround described in Update#3 above :-)
My first reaction is that in JBoss it's not possible to override the log4j configuration like that. JBoss isn't allowing log4j to locate its own configuration, as it normally would, the location of conf/jboss-log4j.xml is specified in conf/jboss-service.xml.
To my knowledge, all log4j configuration in a given JBoss server must be centralised in to a single file, usually conf/jboss-log4j.xml.
Have you tried, as a test, moving the contents of your log4j.properties into the existing conf/jboss-log4j.xml file? If that works fine, then the problem is almost certainly caused by your attempt to override log4j. Having said that, I'd be surprised if jboss/log4j is that fragile, but perhaps in certain cases, it rejects this.
you either have two classes of different signatures but the same path in your environment or you compiled against another signature of j.u.r.Matcher. Since this is standard Java API, I think you should check your source and compilation targets and the JVM runtime version of your JBoss installation.
Edit:
After that is ruled out, I'm sure, the classloader (the server's) that manages the appenders and tries to load the appender that's using your custom layout can't see the custom layout class instance. So you have two options:
Deploy your custom layout JAR to the server's lib-directory along with log4j.
Deploy log4j along with your application and isolate the application with your own classloader (jboss-app.xml):
<jboss-app>
<loader-repository>
com.myapplication:loader=MyClassLoader
<loader-repository-config>java2ParentDelegation=false</loader-repository-config
</loader-repository>
</jboss-app>
I hope, the problem will go away then.