Access .tlb from JAVA - java

Currently trying to access a type library file from JAVA, I have tried the following with corresponding errors:
1- Com2Java: I receive this Error Each time I try to connect to my application:
Minidumps are not enabled by default on client versions of Windows
2- Com4j: It produces only interfaces and Couldn't understand how to use them (I can't find any classes, just interfaces)
3- After a small search, found out about Visual J++ but couldnt download it coz it was discontnued.
Could anyone give advice?
Thank you

I have not used Com2Java or Com4j before, but a long time ago I used a library called JavaCOMBridge (https://sourceforge.net/projects/jacob-project/).
The version of JavaCOMBridge I used cannot handle multiple inheritance, and I don't see how there can be a good way to do it.
Forget about Visual J++. It's an abomination created by Microsoft and was sued into oblivion.
If you are experienced in both C and Java, and the amount of APIs you have to bridge is not large, I'd recommend using JNI directly.
Edit
Here's an example using Excel:
package test;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class JaCoBTest {
public static void main(String[] args) {
String EXCEL_FILE = "FullPathOfAnExcelFile.xlsx";
// Using Excel as an example
ActiveXComponent app = new ActiveXComponent("Excel.Application");
// Modify a property, to show Excel window
app.setProperty("Visible", true);
// Get Excel workbook object
Dispatch workbook = app.getProperty("Workbooks").toDispatch();
// Call method, to open an Excel file
Dispatch.call(workbook, "Open", new Variant(EXCEL_FILE), new Variant("1"));
// Wait for 5 seconds
try {
Thread.sleep(1000);
} catch (InterruptedException iex) {
iex.printStackTrace();
}
// Close Excel without saving
workbook.call(workbook, "Close");
// Close is supposed to have three optional parameteters, but the line below is not working
//workbook.call(workbook, "Close", new Variant(false), Variant.DEFAULT, Variant.DEFAULT);
// Close Excel
Dispatch.call(app, "Quit");
}
}
There is one problem in the above code - I cannot get optional parameters to work. The function Workbook.Close is supposed to take three optional parameters, but the call always fail with invalid number of parameters.
I've also located the web page I used back then:
http://danadler.com/jacob/
The above page contains a link to a FAQ but it's slightly outdated.

Related

How to have only one instance of the CHM file opened?

I want to set up only one instance of the CHM file when clicking on "Help" in the menubar and stopping it from opening twice when clicked again - therefore how do I code it?
I've tried to use it with process.isAlive(), but after I close it I want a counter set to zero, which only opens another CHM file when the counter is 0.
helpMenu.addMouseListener(new MouseAdapter() {
// do this after clicked
openCHM();
});
So MouseEvent is fired once.
openCHM() {
Process p;
if(cnt == 0) {
p = Runtime.getRuntime().exec("hh.exe Help.chm");
cnt++;
if(!p.isAlive()) {
cnt = 0;
}
}
I expected the counter to be 0, but then came to the conclusion that MouseEvent already fired once and the code got already executed, therefore it never goes to the second if-statement and sets my counter to 0.
EDIT
There is no correct answer how to open a CHM file once, but there is a workaround that makes it possible, we just need to look if the file is renamable or not.
protected void openCHM() {
try {
File file = new File("YOURNAME.chm");
boolean renamable = file.renameTo(file); // can't rename if file is already open, returns true if renaming is possible
if(renamable) {
Runtime.getRuntime().exec("hh.exe YOURNAME.chm");
} else if(!file.exists() ){
// message: file doesn't exist (in path)
} else {
// file is already open
}
} catch () {
}
}
I'm not a Java programmer but the short story - not possible (AFAIK).
You know, hh.exe is the HTMLHelp executable and associated with *.CHM files. It's just a shell that uses the HTML Help API and is really just hosting a browser window.
HH.EXE is not single instance, if you open a CHM or another file three times using HH.EXE, then three help windows will appear. Try it using PowerShell:
PS D:\_working> hh.exe C:\Windows\Help\htmlhelp.chm
Several client-side command line switches are available to help authors that are part of the HTML Help executable program (hh.exe) and therefore work when HTML Help Workshop is not set up.
KeyHH.exe was running years ago with special parameters.
If you call the HH API directly from your application, and not via a second helper program like HH.EXE or KEYHH.EXE, then you MUST close any open help windows before shutting down the application or you will probably crash Windows.
For some information related to the problem you maybe interested in Open CHM File Once.
Some quoted info from the link above:
When you do that you are just calling the help viewer again and again from the command line, you're not using the HTML Help API which is what you need to access the CHM once it is open. You need to check whether your flavors of Java and Smalltalk support calls to the HTML Help API. This API is documented in detail in the help file of Microsoft HTML Help Workshop, which is the compiler package you installed to be able to generate CHMs.

Is there any API in drools to create the drl files dynamically by just passing values?

I know how to create DRL files inside KIE workbench by using all the methods. But what my problem is without using the KIE workbench, can we create the .drl file by using our required values.If any possibility is there please suggest me. Same way suggest me any API is regarding to that. Thanks in advance.
You can use Drools Fluent API. Try below sample code :
package com.sample;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import org.drools.lang.DrlDumper;
import org.drools.lang.api.DescrFactory;
import org.drools.lang.descr.PackageDescr;
#SuppressWarnings("restriction")
public class Drl_Creator {
public static void main(String str[]){
PackageDescr pkg = DescrFactory.newPackage()
.name("org.drools.example")
.newRule().name("Xyz")
.attribute("ruleflow-grou","bla")
.lhs()
.and()
.pattern("Foo").id( "$foo", false ).constraint("bar==baz").constraint("x>y").end()
.not().pattern("Bar").constraint("a+b==c").end().end()
.end()
.end()
.rhs( "System.out.println();" ).end()
.getDescr();
DrlDumper dumper=new DrlDumper();
String drl=dumper.dump(pkg);
System.out.print(drl);
try{
// create new file
File file = new File("src/main/rules/test.drl");
file.createNewFile();
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(drl);
// close connection
bw.close();
System.out.println("File Created Successfully");
}catch(Exception e){
System.out.println(e);
}
}
}
I interpret your question in two different ways.
1. Is it possible to write rules for Drools without using the KIE workbench?
Yes, it should support importing rules so all you need to do is open up a text editor and start typing. The rules are written as text using a fairly simple syntax that you can figure out in about 1-2 hours of reading. I do not know what your environment looks like but there should be a mechanism to parse and import a new rule. All rules you write will start out in a text editor looking like this:
rule "<name>"
<attribute>
when
<conditional element>
then
<action>
end
You will add to the conditions and actions. Of course you will have to know what conditions you can create which is limited to your environment and likewise for the actions.
2. Is it possible to create rules and use them programatically through some sort of API?
Yes, I do it all of the time for the processing we do using the Java API. We have 2 types of rules that we use, static and dynamic. The static ones have pre-canned conditions and are written to perform the same comparisons (LHS) over and over and performing the same actions each time the conditions are met (RHS). The dynamic ones are created on the fly based upon a minimalistic set of object types and comparisons (LHS) specified by the user when they are created. The actions (RHS) are pre-canned but are selected for use depending on the need for the overall rule use. The entire rule is created as text then passed to the Drools parser before being added to the list of rules to evaluate.
Hope this helps.
Another option is to use the "descr" APIs, starting from the factory:
org.drools.compiler.lang.api.DescrFactory
These APIs build the Drools AST, which can be passed directly to the compiler,
bypassing the parser. The AST can also be used to recreate DRL, using the
helper class org.drools.compiler.lang.DrlDumper
The standard tools don't produce DRL files. Instead they encourage you to have templates which are applied to your data at runtime.
You should take a look at the documentation on Decision Tables (specially structured spreadsheets):
http://docs.jboss.org/drools/release/6.0.1.Final/drools-docs/html_single/#d0e4221
... and Rule Templates:
http://docs.jboss.org/drools/release/6.0.1.Final/drools-docs/html_single/#d0e4969
Even i have used the same implementation that #apandey846 suggested. I would just like to add one more thing: If you want to import the required classes, you can do it as follows:
PackageDescr pkg = DescrFactory.newPackage()
.newImport("classname").target().end()
.name("org.drools.example")
.newRule().name("Xyz")
.attribute("ruleflow-grou","bla")
.lhs()
.and()
.pattern("Foo").id( "$foo", false ).constraint("bar==baz").constraint("x>y").end()
.not().pattern("Bar").constraint("a+b==c").end().end()
.end()
.end()
.rhs( "System.out.println();" ).end()
.getDescr();
To add multiple conditions in the LHS, you can do:
pattern("eval").constraint("condition1").end().
pattern("eval").constraint("condition2").end().
pattern("eval").constraint("condition3").end().
Hope it helps.. :)
Decesion tables have worked for me alternatively you could try using the new Drools workbench.
I have used the DrlDescr dump method but it is Not updating the drl file, Does anybody have any idea why?
Code:-
pkg1.addRule(rules);
System.out.println(dDump.dump(pkg1));

Use code generation for executing generic tests

I think I have an interesting question and PERHAPS there is already the answer which is still a secret for me, so I hope to get some helps from expers. :)
So here is the thing:
I work for the test/validation team to test our Java API and basically my job is to follow test plan and write the test code. After writing that for more than two months, I find the codes are really similar. For example:
To test function could return expected result or throw exception correctly, we may need write several .java to run.
1.java set up server connection, connect client and send request, initiate variables with correct values and pass them to the function A, catch the answer and analyse it
2.java set up server connection, connect client and send request, initiate all variables with correct values but one with bad value and pass them to function A, catch the answer and analyse it
3.java set up server connection, connect client and send request, initiate all variables with correct values but two with bad values and pass them to function A, catch the answer and analyse it
so you see in three java test files, the most part of them are the same or similar enough and even copy/paste make the job boring and possible to be wrong.
I wonder whether or not I could define test code corresponding different behavior, then for every test java file, I define a text including the behavior and then a mother class who is in charge of loading the text file and assembling the final test java file according to the text file?
Like this:
Text File:
1) set up server
2) connect client
3) send request
4) initiate variables with correct values
5) initiate variables with correct values but one with bad value
6) initiate variables with correct values but two with bad values
7) catch the result and analyse it
Mother.java
1) load Text file
2) create a son.java
3) find the code corresponding the Text file and write them to son.java
Then the coder open son.java at IDE to check syntax, or import or anything conflict then run it.
Is my idea realizable or not? Is there already something similar?
Any information would be appreciated, thanks a millions in advance!
Honestly, this does not sound like a good use case for code generation. Instead of generating a class for each test case, you should implement a more general testing utility which takes the required input as its data and executes the generic testing code based on this data.
From what you write, this would for example be something like a simple base class for a JUnit test:
abstract class AbstractServerDependantTest {
protected Server server;
protected Client client;
#Before
public void setUp() {
server = new Server();
server.start();
client = new Client();
client.connectTo(server);
}
#After
public void tearDpwm() {
client.disconnect();
server.shutDown();
}
}
Now you can write three test classes which inherit from this AbstractServerDependantTest without copy pasting your code.

How to run vbscript function from java?

From java code i am able to run the vbscript by using this code
Runtime.getRuntime().exec("wscript C:\\ppt\\test1.vbs ");
But want to know how to call the method of vbscript from java..for example in test1.vbs
Set objPPT = CreateObject("PowerPoint.Application")
objPPT.Visible = True
Set objPresentation = objPPT.Presentations.Open("C:\ppt\Labo.ppt")
Set objSlideShow = objPresentation.SlideShowSettings.Run.View
sub ssn1()
objPPT.Run "C:\ppt\Labo.ppt!.SSN"
End sub
how to call only ssn1() method from java.Otherwise can we run the macro of a power point from java code..kindly help!!
This should make you happy :) Go to the WScript section : http://technet.microsoft.com/library/ee156618.aspx
Here's my idea... in your vbscript file, make your script listen to a command line parameter that would specify which method to call. Then, in Java, you could only have to use this parameter whenever you want to call a specific method in the file.
Otherwise, if you want to access powerpoint in java, you will need to access its API like you did in vbscript, which is possible if vbscript can do it but the approach / syntax may change.
I'm not so much into the visual basic script side, but if you can expose your visual basic script as a COM object, the you can access the methods of it from java by usage of frameworks such as for example com4j:
http://com4j.java.net/
The PowerPoint application object's .Run method lets you call any public subroutine or function in any open presentation or loaded add-in
This post answers the OP's question:
Otherwise can we run the macro of a power point from java code..kindly help!!
(but does not address the original vbscript question)
There's the JACOB library, which stands for Java COM Bridge, you can find here: http://sourceforge.net/projects/jacob-project/?source=directory
With it you can invoke Excel, Word, Outlook, PowerPoint application object model methods.
I've tried this with Excel but not PowerPoint. (This is just some sample code, one might want to make it more object oriented.)
public class Excel {
private static ActiveXComponent xl = null;
public static Init() {
try {
ComThread.InitSTA();
xl = ActiveXComponent.connectToActiveInstance("Excel.Application.14");
// 14 is Office 2010, if you don't know what version you can do "Excel.Application"
if (xl==null) {
// code to launch Excel if not running:
xl = new ActiveXComponent("Excel.Application");
Dispatch.put(xl, "Visible", Constants.kTrue);
}
}
catch (Exception e) {
ComThread.Release();
}
}
public static String Run(String vbName) {
// Variant v = Dispatch.call(xl, "Run", vbName); // using string name lookup
Variant v = Dispatch.call(xl, 0x103, vbName); // using COM offset
// return Dispatch.get(this, "Name").getString();
return v.getString();
}
public static Variant Run1p(String vbName, Object param) {
// Variant v = Dispatch.call(xl, "Run", vbName, param);
return Dispatch.call(xl, 0x103, vbName, param);
// return Dispatch.get(this, "Name").getString();
}
public static Worksheet GetActiveWorksheet () {
// Dispatch d = xl.getProperty("ActiveSheet").toDispatch();
Dispatch d = Dispatch.get(xl, 0x133).toDispatch ();
return d; // you may want to put a wrapper around this...
}
}
Notes:
For Excel, at least, to get Run to invoke a VBA macro/subroutine several things have to be true:
The Excel workbook containing the macro must be "Active" (i.e. must
be the ActiveWorkbook) otherwise Run will not find the VBA subroutine. (However the workbook does not have to be
screen visible!! This means you can call a VBA Macro that is in an add-in!).
You can then pass the name of the macro using the following syntax as a string literal:
VBAProjectName.VBAModuleName.SubroutineName
For COM object invocations, you can use the name lookup version or the id number version. The id numbers come from the published COM interfaces (which you can find in C++ header files, or possibly have JACOB look them up for you).
If you successfully did the connection to Excel, be sure to call ComThread.Release() when you're done. Put it in some appropriately surrounding finally. If the process of your Java code terminates without calling it, the COM reference count on Excel will be wrong, and the Excel process will never terminate, even after you exit the Excel application. Once that happens, needless to say, Excel starts to behave screwy then (when you try to use it next, it runs but will fail to load any plug-ins/add-ons). If that happens (as it can during debugging esp. if you are bypassing finally's for better debugging) you have to use the task manager to kill the Excel process.

is it possible to create a java applet, during execution of another java application

I have been developing a Java application which executes a long series of queries and calculations, and presents its results as a series of HTML pages. For visualizing graphs I have been playing around with JUNG library for a while, and it appears as the real strength of the library is the support for user interaction, which is of course unavailable when the graph is saved as a static image (PNG in my case).
I was wondering if it would be:
a) possible
b) feasible
c) sensible
... to create an applet, during execution of the main application, which then can be insert to the HTML reports and can be used interactively after the application has finished execution and the user goes through the report pages.
If this is not possible due to technical reasons; do you have any alternative recommendations/ suggestions as to how I can achieve something like this?
Thanks,
EDIT: Just to clarify the concept, the "main" application is a link in a chain of events, and thus has so separate GUI. The idea with the applet is NOT to mimic or transport all the stuff from the main app to a HTML page, but to make it possible to use interactive tools that come with JUNG library, when the user is reviewing the graphical results AFTER the execution of the main software has finished.
Let me know if the concept is still rather unclear and I'll give a second attempt to explain things in further detail.
UPDATE: Following the advices I got, thnx to #boffinBrain & #AndrewThompson, I wrote my applet, and placed in a package in my project along with other visualization related classes. The hierarchy is as follows:
my.domain.project
my.domain.project.tests
my.domain.project.visualization
Now the HTML reports are created at an arbitrary location on the local drive, this is a feature as the user gives an output folder prior to running the "main" application. In my ReportGenerator class (which generates these HTML files) I have the following bit of code:
File bin = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toString());
String codebase = bin.getParent();
System.out.println(codebase);
String archive = "lib/collections-generic-4.01/collections-generic-4.01.jar";
String applet_name = "bin/my.domain.project.visualization.HierarchyGraphApplet.class";
codebase printout shows: file:/home/username/workspace/project which is correct what I'd expected. Under the project folder there's bin/ and lib/, and inside bin there is the right hierarchy of folders all the way down to my applet class which also exists.
Now why did I write all this down; well because when I try to run my applet on the reports I get:
java.lang.NoClassDefFoundError: bin/my/domain/project/visualization/HierarchyGraphApplet (wrong name: my/domain/project/visualization/HierarchyGraphApplet)
I have read similar questions like: this or this but it seems like the problem is somewhere else. I double checked the spelling etc...
Is there something simple I am missing, or is there a more complicated problem at hand?
Maybe this example will give you some ideas to pursue. It creates data files used as 'reports' for consumption by the applet(s).
Because the applet gains the data via an input file whose title is specified in an applet param. The content of the data file is only limited by the requirements of the report, your skill to create it & parse it, ..and available disk space. ;)
Compile & run the main(String[]) to (hopefully) see 2 web pages open in tabs of your browser.
import java.awt.Desktop;
import javax.swing.*;
import java.net.*;
import java.io.*;
/** Simplistic example, not intended to show good I/O practices
or Exception handling for the sake of brevity. */
public class Reporter extends JApplet {
public void init() {
String input = getParameter("input");
JEditorPane report = new JEditorPane();
report.setText("Problem loading input file");
add(report);
URL url;
try {
url = new URL(getDocumentBase(), input);
report.setPage(url);
} catch(Exception e) {
e.printStackTrace();
}
}
/** The main represents our report generator. It is part
of the applet class only in order to create an SSCCE. Good
design would imply that it might be in a class ReportGenerator,
while the applet is in class ReportViewer. */
public static void main(String[] args) throws Exception {
File f;
String title = "1";
String data = "apples";
createInput(title, data);
f = createHTML(title);
Desktop.getDesktop().browse(f.toURI());
title = "2";
data = "oranges";
createInput(title, data);
f = createHTML(title);
Desktop.getDesktop().browse(f.toURI());
System.out.println( "End of report generation.." );
}
public static void createInput(String title, String data) throws Exception {
File f = new File("data" + title + ".txt");
PrintWriter pw = new PrintWriter(f);
pw.println(data);
pw.flush();
pw.close();
}
public static File createHTML(String title) throws Exception {
File f = new File("Data" + title + ".html");
PrintWriter pw = new PrintWriter(f);
pw.println("<html>");
pw.println("<title>");
pw.println("Data " + title);
pw.println("<title>");
pw.println("<body>");
pw.println("<h1>");
pw.println("Data " + title);
pw.println("</h1>");
pw.println("<applet ");
pw.println("code='Reporter'");
pw.println("width='400'");
pw.println("height='400'");
pw.println(">");
pw.println("<param name='input' value='data" + title + ".txt'>");
pw.println("</applet>");
pw.println("</body>");
pw.println("</html>");
pw.flush();
pw.close();
return f;
}
}
In relation to further questions:
..does the given code assume that the html reports and the applet are located in the same folder?
Not necessarily. The input parameter might specify ../other/data3.txt for the other directory at the same level as the one contained by the HTML, or /reports/data3.txt for a reports directory at the root of the site.
..As you have also noted, in a real-life example the code for the applet would most likely be in its own class, would that pose any complications as to how it would be incorporated into the html files (which are generated in a separate class, named ReportGenerator)?
It would require only slight changes to point to the applet.jar as opposed to the application.jar. Use a codebase to separate the HTML from the directory of the applet.jar (though archives can also be accessed via relative or absolute URLs).
It's definitely feasible to create an applet to display the data, but you don't want to dynamically generate a new one each time. You want to create a separate, stand-alone applet which can generate your graphs/reports from a set of input data in text format, and then when you create the HTML page, supply the report data using an applet parameter (using the PARAM tag).

Categories

Resources