How to use automatic proxy configuration script in Java - java

My Internet Explorer is set to have an automatic proxy file(so-called PAC) for web access. Is there a way to use this on my Java program, also ?
My below Java code does not seem to use proxy at all.
ArrayList<Proxy> ar = new ArrayList<Proxy>(ProxySelector.getDefault().select(new URI("http://service.myurlforproxy.com")));
for(Proxy p : ar){
System.out.println(p.toString()); //output is just DIRECT T.T it should be PROXY.
}
I also set my proxy script on Java Control Panel(Control->Java), but the same result.
and I found there's no way to set PAC file for Java programmatically.
People use http.proxyHost for System.setProperties(..) but this is a only for setting proxy host, not proxy script(PAC file).

Wow! I could load Proxy Auto-Config (PAC) file on Java. Please see below codes and package.
import com.sun.deploy.net.proxy.*;
.
.
BrowserProxyInfo b = new BrowserProxyInfo();
b.setType(ProxyType.AUTO);
b.setAutoConfigURL("http://yourhost/proxy.file.pac");
DummyAutoProxyHandler handler = new DummyAutoProxyHandler();
handler.init(b);
URL url = new URL("http://host_to_query");
ProxyInfo[] ps = handler.getProxyInfo(url);
for(ProxyInfo p : ps){
System.out.println(p.toString());
}
You already have a [com.sun.deploy.net.proxy] package on your machine!
Find [deploy.jar] ;D

Java does not have any built-in support for parsing the JS PAC file. You are on your own. What you can do is download that file and parse the proxy host from it. You should read this.

In my case, I've just figured-out what the .pac file will return, then hardcode.

Based on #Jaeh answer I used the code below.
Note that SunAutoProxyHandler implements AbstractAutoProxyHandler and there is an alternative concrete implementation called PluginAutoProxyHandler but that implementation does not appear to be as robust:
BrowserProxyInfo b = new BrowserProxyInfo();
b.setType(ProxyType.AUTO);
b.setAutoConfigURL("http://example.com/proxy.pac");
SunAutoProxyHandler handler = new SunAutoProxyHandler();
handler.init(b);
ProxyInfo[] ps = handler.getProxyInfo(new URL(url));
for(ProxyInfo p : ps){
System.out.println(p.toString());
}

Related

create `KafkaServer` from Java

I am trying to start a Kafka server form Java
Specifically, how can I translate this line of Scala into a line of Java?
private val server = new KafkaServer(serverConfig, kafkaMetricsReporters = reporters)
I can create the serverConfig easily, but I can't seem to be able to create the kafkaMetricsReporters parameter.
Note: I can create a KafkaServerStartable but I would like to create a normal KafkaServer to avoid the JVM exiting in case of error.
Apache Kafka version 0.11.0.1
The kafkaMetricsReporters parameter is a scala Seq.
You can either:
Create a Java collection and convert it into a Seq:
You need to import scala.collection.JavaConverters:
List<KafkaMetricsReporter> reportersList = new ArrayList<>();
...
Seq<KafkaMetricsReporter> reportersSeq = JavaConverters.asScalaBufferConverter(reportersList).asScala();
Use KafkaMetricsReporter.startReporters() method to create them for you from your configuration:
As KafkaMetricsReporter is a singleton, you need to use the MODULE notation to use it:
Seq<KafkaMetricsReporter> reporters = KafkaMetricsReporter$.MODULE$.startReporters(new VerifiableProperties(props));
Also the KafkaServer constructor has 2 other arguments that are required when calling it from Java:
time can easily be created using new org.apache.kafka.common.utils.SystemTime()
threadNamePrefix is an Option. If you import scala.Option, you'll be able to call Option.apply("prefix")
Putting it all together:
Properties props = new Properties();
props.put(...);
KafkaConfig config = KafkaConfig.fromProps(props);
Seq<KafkaMetricsReporter> reporters = KafkaMetricsReporter$.MODULE$.startReporters(new VerifiableProperties(props));
KafkaServer server = new KafkaServer(config, new SystemTime(), Option.apply("prefix"), reporters);
server.startup();

Instrumentate a distant java application via javassist+javaagent+jmx

Actually i want to developpe a java application witch should instrumentate another java application witch i don't have its source code..
I tried to create an agent and attach it to the jvm.. then i created an mbean and tried to connect to it.. it works when i try to instrumentate a class in my project.. but i don't know how could i instrument a distant application with my application..
here is my code: https://github.com/ammouna8ammouna/Monitoring.git
i am really new at the instrumentation world and i really need help.
If you can get the processID of the VM that you are targeting you can attach your agent using
com.sun.tools.attach.VirtualMachine
For example if you have pid, the path of your JAR target and the loader that handle the JAR you can try something like this:
private static void attach(String pid, String jarPath,
ClassLoader toolLoader) throws Exception {
Class<?> attacherLib = toolLoader.loadClass("com.sun.tools.attach.VirtualMachine");
Class<?> string = toolLoader.loadClass("java.lang.String");
Method attach = attacherLib.getMethod("attach", string);
Object instance = attach.invoke(null, pid);
Method loadAgent = attacherLib.getMethod("loadAgent", string, string);
loadAgent.invoke(instance, jarFilePath, "");
Method detach = attacherLib.getMethod("detach");
detach.invoke(instance);
}
Let me know if it's clear or you need other help.

How to run a MATLAB file (.m file) from java?

I am trying to figure out a way to run a .m file from java.
When the .m file is run it outputs a text file that I need to retrieve. I already have the code to retrieve the text file in java but I still cannot figure out how to start and run the .m file from java so that it outputs the file that I need. Any ideas?
You can just start a Java process and run matlab..."matlab -r "yourMfile"
Here is the code, you are looking for:
import matlabcontrol.*;
public class matlabconnect
{
public static void main(String[] args)
throws MatlabConnectionException, MatlabInvocationException
{
// create proxy
MatlabProxyFactoryOptions options =
new MatlabProxyFactoryOptions.Builder()
.setUsePreviouslyControlledSession(true)
.build();
MatlabProxyFactory factory = new MatlabProxyFactory(options);
MatlabProxy proxy = factory.getProxy();
// call builtin function
proxy.eval("disp('hello world')");
// call user-defined function (must be on the path)
proxy.feval("matlab_file_name");
// close connection
proxy.disconnect();
}
I have tested the program. It is working well. Do not forget to put your matlab file to its default path.
There is already a bit newer api for matlab / JAVA
<dependency>
<groupId>com.diffplug.matsim</groupId>
<artifactId>matconsolectl</artifactId>
<version>4.5.0</version>
</dependency>
and
// create proxy
MatlabProxyFactoryOptions.Builder builder = new MatlabProxyFactoryOptions.Builder();
MatlabProxyFactory factory = new MatlabProxyFactory(builder.build());
// get the proxy
MatlabProxy proxy = factory.getProxy();
// call user-defined function (must be on the path)
proxy.eval("addpath('"...PATH..."')");
proxy.feval("function");
// close connection
proxy.disconnect();
I think MatlabControl is what you want. It's all described here: http://www.cs.virginia.edu/~whitehouse/matlab/JavaMatlab.html
In essence, call
MatlabControl.eval("yourfile.m");

Finding out Java options used by Java application

Is there any way where I can find out which Java options are being used by a Java application inside JVM (e.g. the ones passed through the command line)?
I want to find it on the fly when the application is running, but from outside outside the application.
Map<String, String> env = System.getenv();
for (String envName : env.keySet()) {
System.out.format("%s=%s%n", envName, env.get(envName));
}
You can use JMX:
final JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(connectorAddress));
final MBeanServerConnection mBeanServerConnection = connector.getMBeanServerConnection();
final ObjectName commandLine = new ObjectName("java.lang:type=Runtime");
final List<Attribute> arguments = mBeanServerConnection.getAttributes(commandLine, new String[] {"InputArguments"}).asList();
String[] inputArguments = (String[]) arguments.get(0).getValue();
System.out.println(Arrays.asList(inputArguments));
connector.close();
To get the JMX connection, you might find my answer to " JMX client accessible locally only " helpful.
Use JMX. It allows to get options, properties, etc. from inside as well as outside of application.
I believe that Java does not support the "INTERCEPTING" of method arguments, method args are not logged or intercepted in the JVM .
However, you can easily print out the args sent to a running class using the System.env example in the other answer on this thread .
HOWEVER, if you have control over the actual applications source code, you can follow the directions here : How do I intercept a method invocation with standard java features (no AspectJ etc)?
This will allow you to log and intercept the args being sent to the main method.

Is it possible to end a process nicely in a Java application?

In a Java application:
currentProcess = Runtime.getRuntime().exec("MyWindowsApp.exe");
...
currentProcess.destroy();
Calling destroy simply kills the process and doesn't allow any user cleanup or exit code to run. Is it possible to send a process a WM_CLOSE message or similar?
You could use Process.getOutputStream to send a message to the stdin of your app, eg:
PrintStream ps = new PrintStream(currentProcess.getOutputStream());
ps.println("please_shutdown");
ps.close();
Of course this means you have to contrive to listen on stdin in the Windows app.
you can try with JNA, importing user32.dll and defining an interface that defines at least CloseWindow
Using JNA's jna.jar and process.jar (from http://jna.java.net/) you send a WM_CLOSE message as follows:
int WM_CLOSE = 0x10;
HWND hwnd = User32.INSTANCE.FindWindow(null, windowTitle);
User32.INSTANCE.PostMessage(hwnd, WM_CLOSE, new WinDef.WPARAM(), new WinDef.LPARAM());
Not without resorting to native code. Process.destroy() causes a forced termination. On Windows this is equivalent to calling TerminateProcess(). On Unix it is equivalent to a SIGQUIT and causes the application to core dump.
A dirty solution would be making your MyWindowsApp register its identifier somewhere like file and create another windows app that sends WM_CLOSE (let's name it MyWindowsAppCloser) to another applications.
With this in hand, you would code the following using java 1.6
currentProcess = Runtime.getRuntime().exec("MyWindowsApp.exe");
...
// get idMyWindowsApp where MyWindowsApp stored its identifier
killerProcess = new ProcessBuilder("MyWindowsAppCloser.exe", idMyWindowsApp).start();
killerProcess.waitFor();
int status = currentProcess.waitFor();

Categories

Resources