NullPointerException in Custom ClassLoader - Can't find zipEntry - java

I'm making a classloader which can take a jar, and based on that, it can take a package name, and is allowed to load only classes that are in that package. When I try to load a class from there I get the error :
Exception in thread "main" java.lang.NullPointerException
at com.classloader.CustomClassLoader.getClassBytes(CustomClassLoader.java:64)
at com.classloader.CustomClassLoader.getClass(CustomClassLoader.java:48)
at com.classloader.CustomClassLoader.loadClass(CustomClassLoader.java:89)
at com.classloader.TestJar.main(TestJar.java:46)
Even though the package name and entry name are correct. Any ideas where the problem is and how to fix it ? The code is below and I believe it's pretty self explanatory.
CustomLoader
package com.classloader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
public class CustomClassLoader extends ClassLoader implements LoaderConstraints {
private Map<String, Class> loaded = new HashMap<String, Class>();
private Map<String, String> available = new LinkedHashMap<String, String>();
private Set<String> allowed = new LinkedHashSet<String>();
public Set<String> getPermited() {
return allowed;
}
public Map<String, String> getAvailable() {
return available;
}
public Map<String, Class> getLoaded() {
return loaded;
}
public CustomClassLoader() {
super(CustomClassLoader.class.getClassLoader());
}
private Class<?> getClass(String className, String pack) throws ClassNotFoundException {
Class<?> c = null;
String classPath = className.replace('.', File.separatorChar) + ".class";
byte[] b = null;
try {
b = getClassBytes(classPath, pack);
c = defineClass(className, b, 0, b.length);
resolveClass(c);
return c;
} catch (IOException e) {
e.printStackTrace();
}
return c;
}
private byte[] getClassBytes(String classPath, String pack) throws IOException {
ZipFile zip = new ZipFile(pack);
// System.out.println(classPath); classPath is right , as well as pack
ZipEntry entry = zip.getEntry(classPath);//This return null, for some reason ???
InputStream in = zip.getInputStream(zip.getEntry(classPath));
long size = entry.getSize();
byte buff[] = new byte[(int)size];
in.read(buff);
in.close();
return buff;
}
#Override
public Class<?> loadClass(String className) throws ClassNotFoundException {
Class<?> found = null;
if(loaded.get(className) != null){
return loaded.get(className);
}
if(available.get(className ) != null){
if(allowed.contains(className ) == true){
found = getClass(className, available.get(className));
if(found != null)
loaded.put(className, found);
}
}
else{
found = super.loadClass(className);
if(found != null)
loaded.put(className, found);
}
return found;
}
public void files(ZipFile zip, Map<String,String> list) throws ZipException, IOException{
Enumeration<? extends ZipEntry> entries = zip.entries();
while(entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (!entry.isDirectory() && entry.getName().endsWith(".class")) {
String className = entry.getName().replace('/', '.');
list.put(className.substring(0, className.length() - ".class".length())
,zip.getName());
}
}
}
public void addJar (File jarFile) {
try {
files(new ZipFile(jarFile), available);
} catch (ZipException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void deleteJar(File jarFile) {
Map<String,String> removes = new HashMap<String, String>();
try {
files(new ZipFile(jarFile), removes );
} catch (ZipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
available.keySet().removeAll(removes.keySet());
}
public void allowPackage(final String p) {
for(String s : available.keySet()){
if(s.startsWith(p))
allowed.add(new String(s));
}
}
public void denyPackage(final String p) {
Set<String> newPermited = new HashSet<String>();
for(String s : allowed){
if(!s.startsWith(p))
newPermited.add(new String(s));
}
allowed = newPermited;
}
}
Test
public static void main(String[] args) throws ZipException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
CustomClassLoader ccl = new CustomClassLoader();
ccl.addJar(new File("derby.jar"));
ccl.allowPackage("org.apache.derby.jdbc");
//System.out.println(ccl.getAvailable().get("org.apache.derby.jdbc.EmbeddedDriver")); --> returns "derby.jar"
Class<?> clazz = ccl.loadClass("org.apache.derby.jdbc.EmbeddedDriver");//Gives exception , line 46
System.out.println(clazz.getClass());
Object instance = clazz.newInstance();
System.out.println(instance.getClass());
}
The derby.jar is located in the project folder. Any help is welcomed :)

Try to replace File.separatorChar with '/'

Related

when invoking a java method by method.invoke() its not returning any value instead print in the console log

Hello please help me to find a solution for this problem, I'm creating an web compiler for java programs I have implemented the java inbuilt compiler class to compile the code and its also giving the output but it's giving output in the console and I want that output in the return object or some string variable so I can display the output in front. I'm attaching full code.
package online_compiler.web;
import java.io.BufferedReader;
import java.io.Console;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
public class compiler {
public static void myMethod(String name) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
int result;
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
String program = "public class Main{" + " public static void main (String [] args){"
+ " System.out.println (\"Hello, World\");"
+ " }" + "}";
JavaSourceFromString jsfs = new JavaSourceFromString("Main", program);
Iterable<? extends JavaFileObject> fileObjects = Arrays.asList( jsfs);
java.util.List<String> options = new ArrayList<String>();
options.add("-d");
options.add("C:\\Program Files\\Java\\jdk-12.0.2\\bin");
options.add( "-classpath");
URLClassLoader urlClassLoader =
(URLClassLoader)Thread.currentThread().getContextClassLoader();
StringBuilder sb = new StringBuilder();
for (URL url : urlClassLoader.getURLs()) {
sb.append(url.getFile()).append(java.io.File.pathSeparator);
}
sb.append("C:\\\\Program Files\\\\Java\\\\jdk-12.0.2\\\\bin");
options.add(sb.toString());
StringWriter output = new StringWriter();
boolean success = compiler.getTask( output, null, null, options, null, fileObjects).call();
if(success) {
name = output.toString();
System.out.print(output);
java.io.File root = new java.io.File("C:\\\\Program Files\\\\Java\\\\jdk-12.0.2\\\\bin");
URLClassLoader classLoader;
try {
classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
Object obj = null;
Class<?> cls = Class.forName("Main", true, classLoader);
try {
obj = cls.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Method m = cls.getMethod("main", new Class[] { String[].class });
Object[] _args = new Object[] { new String[0] };
Object retobj = m.invoke(obj, _args);
System.out.println(retobj);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//logger.info( LOG_PREFIX + "Class has been successfully compiled");
} else {
//throw new Exception( "Compilation failed :" + output);
}
}
static Iterable<JavaSourceFromString> getJavaSourceFromString(String code) {
final JavaSourceFromString jsfs;
jsfs = new JavaSourceFromString("code", code);
return new Iterable<JavaSourceFromString>() {
public Iterator<JavaSourceFromString> iterator() {
return new Iterator<JavaSourceFromString>() {
boolean isNext = true;
public boolean hasNext() {
return isNext;
}
public JavaSourceFromString next() {
if (!isNext)
throw new NoSuchElementException();
isNext = false;
return jsfs;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
}
class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
The main driver code is this
enter image description here
output in the console log
I have tried many things searching on internet but nothing worked. I want that output in an object or a string variable so I can use that output or that string to front end.
The method you call is static void main. It doesn't return any value.
If you create a method that actually returns something, it should work better

Character encoding in com.sun.net.httpserver

I'm trying to write a mock HTTP server for unit tests, I'm using the com.sun.net.httpserver classes for that.
I'm having problem with the encoding of the URL: the query parameters are ISO-8859-1 encoded, but the URI that is passed to the handler (via HttpExchange) is not.
As I can't change the encoding of the original server, I was wondering if there was a way to tell the HttpServer which encoding to use when decoding the URL.
Thanks in advance.
Here is a test program:
package test34;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
public static void main(String[] args) {
try {
MockServer mock = new MockServer();
mock.start(8642);
URL url = new URL("http://localhost:8642/?p="
+ URLEncoder.encode("téléphone", "ISO-8859-1"));
System.out.println(url);
InputStream in = url.openStream();
while (in.read() > 0) {
}
in.close();
mock.stop();
System.out.println(mock.getLastParams().get("p"));
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
And here is the code of the mock server:
package test34;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class MockServer {
private HttpServer httpServer;
private Map<String, String> params;
public void start(int port) {
if (httpServer == null) {
try {
InetSocketAddress addr = new InetSocketAddress(port);
httpServer = HttpServer.create(addr, 0);
httpServer.createContext("/", new HttpHandler() {
#Override
public void handle(HttpExchange exchange) throws IOException {
try {
handleRoot(exchange);
} catch (RuntimeException e) {
throw e;
} catch (IOException e) {
throw e;
}
}
});
httpServer.setExecutor(Executors.newFixedThreadPool(1));
httpServer.start();
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
}
}
public void stop() {
if (httpServer != null) {
httpServer.stop(10);
httpServer = null;
}
}
public Map<String, String> getLastParams() {
Map<String, String> result = new HashMap<String, String>();
if (params != null) {
result.putAll(params);
}
return result;
}
private void handleRoot(HttpExchange exchange) throws IOException {
URI uri = exchange.getRequestURI();
params = parseQuery(uri.getQuery());
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Content-Type", "text/plain;charset=ISO-8859-1");
exchange.sendResponseHeaders(200, 0);
OutputStream stream = exchange.getResponseBody();
try {
Writer writer = new OutputStreamWriter(stream, "ISO-8859-1");
try {
PrintWriter out = new PrintWriter(writer);
try {
out.println("OK");
} finally {
out.close();
}
} finally {
writer.close();
}
} finally {
stream.close();
}
}
private static Map<String, String> parseQuery(String qry)
throws IOException {
Map<String, String> result = new HashMap<String, String>();
if (qry != null) {
String defs[] = qry.split("[&]");
for (String def : defs) {
int ix = def.indexOf('=');
if (ix < 0) {
result.put(def, "");
} else {
String name = def.substring(0, ix);
String value = URLDecoder.decode(
def.substring(ix + 1), "ISO-8859-1");
result.put(name, value);
}
}
}
return result;
}
}
The javadoc of HttpExchange.getQueryString() says it returns "undecoded query string of request URI, or null if the request URI doesn't have one."
If it's not decoded, and since http headers have to be in 7 bit ASCII (ietf.org/rfc/rfc2616.txt) , then you can decode later with URLDecoder.decode(... "ISO-8859-1");

BCEL - Get Class name,element names ,and method names

how to using bcel classparaser to get class names ,element names and method names ?
ive already find a way to get class names but element and method names give me something wrong .
Anyone can help me with that ?
here is my code (with some errors there, and not completed):
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.generic.ConstantPoolGen;
public final class BcelTest
{
// static int methods;
public static void main(String[] args)
{
ClassParser parser;
try
{
JarFile jar = new JarFile("C:\\Users\\OOO\\Desktop\\Sample.Jar");
Enumeration<JarEntry> entries = jar.entries();
ConstantPoolGen cpg = jar.entries();
while (entries.hasMoreElements())
{
JarEntry entry = entries.nextElement();
if (!entry.getName().endsWith(".class"))
continue;
parser =
new ClassParser("C:\\Users\\OOO\\Desktop\\Sample.Jar",
entry.getName());
methods = getMethodName(cpg);
MyClassVisitor visitor = new MyClassVisitor(parser.parse());
visitor.start();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
public String getMethodName(ConstantPoolGen cpg)
{
return getMethodName(cpg);
}
}
You can call parse() on the JavaParser to obtain a JavaClass class, which offers all the required information:
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.Field;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
public final class BcelTest
{
public static void main(String[] args)
{
JarFile jar = null;
try
{
String jarName = "C:/theFile.jar";
jar = new JarFile(jarName);
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements())
{
JarEntry entry = entries.nextElement();
if (!entry.getName().endsWith(".class"))
{
continue;
}
ClassParser parser =
new ClassParser(jarName, entry.getName());
JavaClass javaClass = parser.parse();
System.out.println("Class: "+javaClass.getClassName());
System.out.println(" Fields:");
for (Field field : javaClass.getFields())
{
System.out.println(" "+field);
}
System.out.println(" Methods:");
for (Method method : javaClass.getMethods())
{
System.out.println(" "+method);
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (jar != null)
{
try
{
jar.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
}

map.size() not working with static map

Hey i am trying to get the size of Static map from other class...
i am defining Static map in one class...as
tasklet.class
package com.hcsc.ccsp.nonadj.subrogation.integration;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import com.hcsc.ccsp.nonadj.subrogation.batch.Subrogation;
import com.hcsc.ccsp.nonadj.subrogation.common.SubrogationConstants;
/**
* #author Manan Shah
*
*/
public class SubrogationFileTransferTasklet implements Tasklet,
InitializingBean {
private Logger logger = LogManager
.getLogger(SubrogationFileTransferTasklet.class);
private Resource inputfile;
private Resource outputfile;
public static String fileLastName;
public static String header = null;
public static String trailer = null;
public static List<Subrogation> fileDataListSubro = new ArrayList<Subrogation>();
public List<String> fileDataListS = new ArrayList<String>();
public static TreeMap<String, Subrogation> map = new TreeMap<String, Subrogation>();
public int counter = 0;
public String value;
#Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(inputfile, "inputfile must be set");
}
public void setTrailer(String trailer) {
this.trailer = trailer;
}
public void setHeader(String header) {
this.header = header;
}
public String getTrailer() {
return trailer;
}
public String getHeader() {
return header;
}
public Resource getInputfile() {
return inputfile;
}
public void setInputfile(Resource inputfile) {
this.inputfile = inputfile;
}
public Resource getOutputfile() {
return outputfile;
}
public void setOutputfile(Resource outputfile) {
this.outputfile = outputfile;
}
public static void setFileDataListSubro(List<Subrogation> fileDataListSubro) {
SubrogationFileTransferTasklet.fileDataListSubro = fileDataListSubro;
}
public static List<Subrogation> getFileDataListSubro() {
return fileDataListSubro;
}
public static void setMap(TreeMap<String, Subrogation> map) {
SubrogationFileTransferTasklet.map = map;
}
public static TreeMap<String, Subrogation> getMap() {
return map;
}
#Override
public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext) throws Exception {
value = (String) chunkContext.getStepContext().getStepExecution()
.getJobExecution().getExecutionContext().get("outputFile");
readFromFile();
return RepeatStatus.FINISHED;
}
public void readFromFile() {
BufferedReader br = null;
try {
String sCurrentLine;
br = new BufferedReader(new FileReader(inputfile.getFile()));
fileLastName = inputfile.getFile().getName();
while ((sCurrentLine = br.readLine()) != null) {
if (sCurrentLine.indexOf("TRAILER") != -1) {
setTrailer(sCurrentLine);
} else if (sCurrentLine.indexOf("HEADER") != -1) {
setHeader(sCurrentLine);
} else if (sCurrentLine.equalsIgnoreCase("")) {
} else {
fileDataListS.add(sCurrentLine);
}
}
convertListOfStringToListOfSubrogaion(fileDataListS);
writeDataToFile();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public void convertListOfStringToListOfSubrogaion(List<String> list) {
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
Subrogation subrogration = new Subrogation();
String s = iterator.next();
subrogration.setGRP_NBR(StringUtils.substring(s, 0, 6));
subrogration.setSECT_NBR(StringUtils.substring(s, 6, 10));
subrogration.setAFP_VAL(StringUtils.substring(s, 10, 13));
subrogration.setDOL_MIN_VAL(StringUtils.substring(s, 13, 20));
subrogration
.setCORP_ENT_CD(StringUtils.substring(s, 20, s.length()));
map.put(subrogration.getGRP_NBR() + subrogration.getSECT_NBR(),
subrogration);
fileDataListSubro.add(subrogration);
}
}
public void writeDataToFile() {
try {
File file = new File(value);
if (!file.exists()) {
logger.info("output file is:-" + file.getAbsolutePath());
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry subrogation = (Map.Entry) it.next();
// System.out.println(subrogation.getKey() + " = " +
// subrogation.getValue());
// it.remove(); // avoids a ConcurrentModificationException
bw.append(subrogation.getValue().toString()
+ SubrogationConstants.filler58);
}
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
logger.info("subrogationFileTransferTasklet Step completes");
}
}
In processor i want to put map size into int.
processor.class
package com.hcsc.ccsp.nonadj.subrogation.processor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.batch.item.ItemProcessor;
import com.hcsc.ccsp.nonadj.subrogation.Utils.SubrogationUtils;
import com.hcsc.ccsp.nonadj.subrogation.batch.Subrogation;
import com.hcsc.ccsp.nonadj.subrogation.common.SubrogationConstants;
import com.hcsc.ccsp.nonadj.subrogation.integration.SubrogationFileTransferTasklet;
public class SubrogationProcessor implements
ItemProcessor<Subrogation, Subrogation> {
public SubrogationFileTransferTasklet fileTransferTasklet = new SubrogationFileTransferTasklet();
SubrogationUtils subrogationUtils = new SubrogationUtils();
public int countFromFile=SubrogationFileTransferTasklet.map.size();
public static int totalRecords = 0;
public static int duplicate = 0;
#Override
public Subrogation process(Subrogation subrogration) throws Exception {
// TODO Auto-generated method stub
if (subrogationUtils.validateData(subrogration)) {
Subrogation newSubro = new Subrogation();
newSubro.setGRP_NBR(StringUtils.leftPad(subrogration.getGRP_NBR()
.trim(), SubrogationConstants.length6, "0"));
if (subrogration.getSECT_NBR().trim().length() < 5) {
newSubro.setSECT_NBR(StringUtils.leftPad(subrogration
.getSECT_NBR().trim(), SubrogationConstants.length4,
"0"));
} else if (subrogration.getSECT_NBR().trim().length() == 5) {
newSubro.setSECT_NBR(StringUtils.substring(subrogration.getSECT_NBR().trim(), 1));
} else {
return null;
}
newSubro.setAFP_VAL(StringUtils.leftPad(subrogration.getAFP_VAL()
.trim(), SubrogationConstants.length3, "0"));
if (subrogration.getDOL_MIN_VAL().trim().contains(".")) {
newSubro.setDOL_MIN_VAL(StringUtils.leftPad(StringUtils.substring(subrogration.getDOL_MIN_VAL(),0,subrogration.getDOL_MIN_VAL().indexOf(".")), SubrogationConstants.length7,
"0"));
} else {
newSubro.setDOL_MIN_VAL(StringUtils.leftPad(subrogration
.getDOL_MIN_VAL().trim(), SubrogationConstants.length7,
"0"));
}
newSubro.setCORP_ENT_CD(StringUtils.substring(
subrogration.getCORP_ENT_CD(), 0, 2));
if (SubrogationFileTransferTasklet.map.containsKey(newSubro
.getGRP_NBR() + newSubro.getSECT_NBR())) {
duplicate++;
return null;
} else {
if(SubrogationFileTransferTasklet.fileLastName.contains("TX")){
if(newSubro.getCORP_ENT_CD().equalsIgnoreCase("TX")){
SubrogationFileTransferTasklet.map.put(newSubro
.getGRP_NBR() + newSubro.getSECT_NBR(), newSubro);
totalRecords++;
return newSubro;
}
}
else{
if(SubrogationFileTransferTasklet.fileLastName.contains("IL")){
if(!newSubro.getCORP_ENT_CD().equalsIgnoreCase("TX"))
{
newSubro.setCORP_ENT_CD("IL");
SubrogationFileTransferTasklet.map.put(newSubro
.getGRP_NBR() + newSubro.getSECT_NBR(), newSubro);
totalRecords++;
return newSubro;
}
}
else{
return null;
}
}
return null;
}
}
else {
return null;
}
}
}
class SubrogrationException extends RuntimeException {
private static final long serialVersionUID = -8971030257905108630L;
public SubrogrationException(String message) {
super(message);
}
}
and at last i want to use that countFromFile in other class..
writer.class
package com.hcsc.ccsp.nonadj.subrogation.writer;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Writer;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileFooterCallback;
import org.springframework.batch.item.file.FlatFileHeaderCallback;
import com.hcsc.ccsp.nonadj.subrogation.Utils.SubrogationUtils;
import com.hcsc.ccsp.nonadj.subrogation.batch.Subrogation;
import com.hcsc.ccsp.nonadj.subrogation.common.SubrogationConstants;
import com.hcsc.ccsp.nonadj.subrogation.integration.SubrogationFileTransferTasklet;
import com.hcsc.ccsp.nonadj.subrogation.processor.SubrogationProcessor;
public class SubrogationHeaderFooterWriter implements FlatFileFooterCallback,FlatFileHeaderCallback{
private Logger logger = LogManager
.getLogger(SubrogationHeaderFooterWriter.class);
SubrogationFileTransferTasklet fileTransferTasklet = new SubrogationFileTransferTasklet();
SubrogationUtils subrogationUtils=new SubrogationUtils();
SubrogationProcessor processor=new SubrogationProcessor();
private ItemWriter<Subrogation> delegate;
public void setDelegate(ItemWriter<Subrogation> delegate) {
this.delegate = delegate;
}
public ItemWriter<Subrogation> getDelegate() {
return delegate;
}
#Override
public void writeHeader(Writer writer) throws IOException {
//writer.write(SubrogationFileTransferTasklet.header);
}
#Override
public void writeFooter(Writer writer) throws IOException {
String trailer = SubrogationFileTransferTasklet.trailer;
String s1 = StringUtils.substring(trailer, 0, 23);
logger.info(" Data from input file size is---- "+new SubrogationProcessor().countFromFile);
int trailerCounter=new SubrogationProcessor().countFromFile+SubrogationProcessor.totalRecords;
logger.info(" Data comming from database is"+SubrogationProcessor.totalRecords);
logger.info(" Duplicate data From DataBase is " +SubrogationProcessor.duplicate);
logger.info(" Traileer is " + s1+ trailerCounter);
writer.write(s1 + trailerCounter);
SubrogationFileTransferTasklet.map.clear();
SubrogationFileTransferTasklet.fileDataListSubro.clear();
SubrogationProcessor.totalRecords=0;
SubrogationProcessor.duplicate=0;
}
public void writeErrorDataToFile(List<String> errorDataList,String errorfile){
File file;
try {
file = new File(errorfile);
logger.info("error file is "+errorfile);
FileWriter fileWriter = new FileWriter(file,true);
BufferedWriter bufferWritter = new BufferedWriter(fileWriter);
for(String data:errorDataList){
bufferWritter.write(new Date()+" "+data);
bufferWritter.write(SubrogationConstants.LINE_SEPARATOR);
}
bufferWritter.close();
}
catch (IOException e) {
throw new ItemStreamException("Could not convert resource to file: [" + errorfile + "]", e);
}
}
/*
public void write(List<? extends Subrogation> subrogation) throws Exception {
System.out.println("inside writer");
delegate.write(subrogation);
}*/
}
so here in logger massage.size prints 0....
I am not able to understand why???
Do in this way to make sure that It is initialized with the current size of the map when object is constructed.
class SubrogationProcessor{
public int countFromFile;
public SubrogationProcessor(){
countFromFile=SubrogationFileTransferTasklet.map.size();
}
}
This depends on when the "map.put" line of code is run. Is it in a static block in the tasklet class?
If processor instance is initialized before record has been added to the map then map.size() will indeed be 0.
my suggestion would be to add the map into a static block if at all possible or to debug the code and see when the .put() method is being called in comparison to when the .size() method is called
public static TreeMap<String, Subrogation> map = new TreeMap<String, Subrogation>();
static{
map.put(subrogration.getGRP_NBR() + subrogration.getSECT_NBR(), subrogration);
}

Why can't the Java class loader find my interface?

In the code below I generate a class dynamically using sun.tools.javac.Main. I will create a new instance of this class using Reflection. The problem is, I want to avoid using Reflection to invoke the method I defined for this class, so I created a ProxyInvoker that references an interface I defined in my project. In order for the classloader to see this, I add the classpath to the Executable interface to my classloader. I still get an error during the 'compilation' step that says that my interface was not found.
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class MyClassGenerator {
static final String generatedClassName = "TestHello_" + System.currentTimeMillis();
static final String javaFileName = generatedClassName + ".java";
static URLClassLoader classLoader;
public static void main(final String args[])
throws MalformedURLException {
final ProxyInvoker proxy = new ProxyInvoker();
generateClass();
loadExecutableInterface();
if (compileClass()) {
System.out.println("Running " + generatedClassName + ":\n\n");
final Executable ex = createExecutable();
ex.execute();
}
else {
System.out.println(javaFileName + " is bad.");
}
}
public static void loadExecutableInterface()
throws MalformedURLException {
final File file = new File("."); // <-- the directory where the generated java class is defined
final File file2 = new File("src"); // <-- the directory where interface Executable is defined
try {
classLoader = URLClassLoader.newInstance(new URL[] { file.toURI().toURL(), file2.toURI().toURL() });
try {
classLoader.loadClass("Executable");
}
catch (final ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
catch (final MalformedURLException e) {
e.printStackTrace();
}
System.out.println(file.toURI().toURL());
System.out.println(file2.toURI().toURL());
}
public static void generateClass() {
try {
final FileWriter aWriter = new FileWriter(javaFileName, true);
aWriter.write("public class " + generatedClassName + " implements Executable {");
aWriter.write("\n");
aWriter.write("\n");
aWriter.write(" public void invoke() {");
aWriter.write(" System.out.println(\"Hello World!\");");
aWriter.write(" }");
aWriter.write("\n");
aWriter.write("}");
aWriter.flush();
aWriter.close();
}
catch (final Exception e) {
e.printStackTrace();
}
}
public static boolean compileClass() {
final String[] source = { new String(javaFileName) };
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
new sun.tools.javac.Main(baos, source[0]).compile(source);
System.out.print(baos.toString());
return (baos.toString().indexOf("error") == -1);
}
public static Executable createExecutable() {
Executable instance = null;
try {
final Class<?> genClass = Class.forName(generatedClassName, true, classLoader);
instance = (Executable) genClass.newInstance();
}
catch (final Exception e) {
e.printStackTrace();
}
return instance;
}
}
class ProxyInvoker {
Executable myExecutable;
public void runIt() {
final Executable myExecutable;
}
}
Here is a working version of your code:
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class MyClassGenerator {
static final String generatedClassName = "TestHello_" + System.currentTimeMillis();
static final String javaFileName = generatedClassName + ".java";
static URLClassLoader classLoader;
public static void main(final String args[])
throws MalformedURLException {
generateClass();
loadExecutableInterface();
if (compileClass()) {
System.out.println("Running " + generatedClassName + ":\n\n");
final Executable ex = createExecutable();
ex.execute();
}
else {
System.out.println(javaFileName + " is bad.");
}
}
public static void loadExecutableInterface()
throws MalformedURLException {
final File file = new File("."); // <-- the directory where the generated java class is defined
try {
classLoader = URLClassLoader.newInstance(new URL[] { file.toURI().toURL() }, Executable.class.getClassLoader());
try {
classLoader.loadClass("Executable");
}
catch (final ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
catch (final MalformedURLException e) {
e.printStackTrace();
}
System.out.println(file.toURI().toURL());
}
public static void generateClass() {
try {
final FileWriter aWriter = new FileWriter(javaFileName, true);
aWriter.write("public class " + generatedClassName + " implements Executable {");
aWriter.write("\n");
aWriter.write("\n");
aWriter.write(" public void execute() {");
aWriter.write(" System.out.println(\"Hello World!\");");
aWriter.write(" }");
aWriter.write("\n");
aWriter.write("}");
aWriter.flush();
aWriter.close();
}
catch (final Exception e) {
e.printStackTrace();
}
}
public static boolean compileClass() {
final String[] source = { "-classpath", "target/classes", javaFileName };
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
new sun.tools.javac.Main(baos, source[0]).compile(source);
System.out.print(baos.toString());
return (baos.toString().indexOf("error") == -1);
}
public static Executable createExecutable() {
Executable instance = null;
try {
final Class<?> genClass = Class.forName(generatedClassName, true, classLoader);
instance = (Executable) genClass.newInstance();
}
catch (final Exception e) {
e.printStackTrace();
}
return instance;
}
}
The main changes: classloader and compilation parts were wrong.

Categories