I have tried tess4j as a standalone java program and it worked properly giving the text output.
Now i am trying to create a spring mvc web project adding the dependencies for tess4j in pom and i have added the tess4j source inside my project.
File imageFile = new File("D:/Data/jars/tess/eurotext.tif");
Tesseract instance = Tesseract.getInstance(); // JNA Interface Mapping
// Tesseract1 instance = new Tesseract1(); // JNA Direct Mapping
try {
result = instance.doOCR(imageFile);
System.out.println(result);
} catch (TesseractException e) {
System.err.println(e.getMessage());
}
The above code works properly when i tried to run a standalone java program inside the project.so its clear that the jar files are added to build path properly.
but when i call the code in a controller mapping or service it throws a run time exception.
SEVERE: Unsupported image format. May need to install JAI Image I/O package.
https://java.net/projects/jai-imageio/
java.lang.RuntimeException: Unsupported image format. May need to install JAI Image I/O package.
https://java.net/projects/jai-imageio/
at net.sourceforge.vietocr.ImageIOHelper.getIIOImageList(ImageIOHelper.java:324)
at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:173)
at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:158)
at com.ocr.tesseract.TesseractExample.getTextFromImage(TesseractExample.java:27)
at com.cogz.tp.controller.HomeController.view(HomeController.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:214)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:748)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:931)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:822)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:409)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1044)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
java.lang.RuntimeException: Unsupported image format. May need to install JAI Image I/O package.
https://java.net/projects/jai-imageio/
Please let me know what am missing.Thanks in advance.
Even I faced the similar problem of using tess4j for DynamicWebProject. But thanks to comment by #nguyenq that helped me I got it working.
Mostly tess4j uses TIFF handler for optical recognition. The dependencies required for it are not available with default ImageIO.
So, jai-imageio.jar is required. All I did was added line ImageIO.scanForPlugins() before I called the wrapper class that performed doOCR.
I had following jars in my lib:-
tess4j.jar
jai_imageio.jar
ghost4j-0.3.1.jar
jna.jar
junit-4.10.jar
Here's the sample code:
TessractOCR tessocr = new TessractOCR();
ImageIO.scanForPlugins();
String extractedString = tessocr.extractTextFromImage(binarizrImage);
The function
public static String extractTextFromImage(BufferedImage image){
RenderedImage img = image;
String result =null;
try {
File outputfile = new File("saved.png");
ImageIO.write(img, "png", outputfile);
Tesseract instance = Tesseract.getInstance(); // JNA Interface Mapping
instance.setDatapath("E:\\OCR-data\\Tess4J-1.2-src\\Tess4J");
result = instance.doOCR(outputfile);
System.out.println(result);
} catch (Exception e) {
System.err.println(e.getMessage());
}
return result;
}
It works 100% :)
Below is the working code sharing for all:
public static String doOCR(File pdfInvoice) {
String result = "";
long totalTime = 0;
long endTime = 0;
long startTime = System.currentTimeMillis();
File imageFile = new File("D:\\docfolder\\9011121584.pdf");
Tesseract instance = Tesseract.getInstance(); //
try {
ImageIO.scanForPlugins();
result = instance.doOCR(imageFile);
endTime = System.currentTimeMillis();
totalTime = endTime - startTime;
System.out.println("Total Time Taken For OCR: " + (totalTime / 1000));
return result;
} catch (Exception e) {
System.err.println(e.getMessage());
result = "";
return result;
}
}
Related
I am asking this question because I was unable to find a similar question. I recently completed this college project where I made a console application that connected to the database and everything seemed perfectly fine. The method I used to connect to the database is this:
private static Connection getConnection()
{
Connection connection = null;
try
{
String dbDirectory = "c:/murach/java/db";
System.setProperty("derby.system.home", dbDirectory);
String dbURL = "jdbc:derby:MurachDB2";
String username = "";
String password = "";
connection = DriverManager.getConnection(dbURL, username, password);
System.out.println("connect works");
return connection;
} //end try connection statement
catch (SQLException e)
{
for (Throwable t : e)
{
e.printStackTrace();
System.out.println("something went wrong on connection method");
} //end for loop for errors
} // end catch statement for connection error
return connection;
}
As I said before I created the console application and everything seemed fine and I turned it in. However, I wanted to experiment with something, I wanted to make another version of this application but instead a GUI application using Jform. I used all of the same classes as before, except that instead of a main class, I used a jform. The method and class is exactly the same, because the database didn't change locations in my folder, however when I run it in the Jform application I get a runtime error.
What it was a null point error and I knew it had something to do with connecting to the database because I wrote a System.out.Println in the catch SQL Exception to notify that something went wrong with the method. The connect to the database is fine with the console application, but my question is if there is any further measures I need to take when it comes to working with a JFrame application. Is there anything I am missing or is there any extra step I need to do. For further measures I will display the whole class that works with the database, and I will also use the event handlers in the Jframe.
I want to make this clear in which that I am not required to do this. I am just playing around with Java, and I could easily leave this alone without consequences, but I feel I really want to learn this so this is why I am asking for help. Any kind of advice or if any of you can let you know what I am missing I would really appreciate it.
Edit
adding error information
>java.sql.SQLException: No suitable driver found for jdbc:derby:MurachDB2
something went wrong on connection method
java.lang.NullPointerException
something went from with dislay part
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at CustomerInvoiceDB.getConnection(CustomerInvoiceDB.java:38)
at CustomerInvoiceDB.getCustomers(CustomerInvoiceDB.java:67)
at CutomerInvoice.displayButtonActionPerformed(CutomerInvoice.java:111)
at CutomerInvoice.access$000(CutomerInvoice.java:24)
at CutomerInvoice$1.actionPerformed(CutomerInvoice.java:57)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6533)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6298)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
at java.awt.Container.dispatchEventImpl(Container.java:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
I have single node Hadoop 1.2.1 cluster running on VM.
My hdfs-site.xml looks like this:
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
<description>Default block replication.
</description>
</property>
<property>
<name>dfs.support.append</name>
<value>true</value>
<description>Does HDFS allow appends to files?
</description>
</property>
</configuration>
Now when I'm trying to run the following code from Eclipse it returns me always false:
Configuration config = new Configuration();
config.set("mapred.job.tracker","10.0.0.6:54311");
config.set("fs.default.name","hdfs://10.0.0.6:54310");
FileSystem fs = FileSystem.get(config);
boolean flag = Boolean.getBoolean(fs.getConf().get("dfs.support.append"));
System.out.println("dfs.support.append is set to be " + flag);
Now If I'm trying to append to existing file I'll get the following error:
org.apache.hadoop.ipc.RemoteException: java.io.IOException: Append is not supported. Please see the dfs.support.append configuration parameter
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.appendFile(FSNamesystem.java:1781)
at org.apache.hadoop.hdfs.server.namenode.NameNode.append(NameNode.java:725)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:587)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1432)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1428)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1190)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:1426)
at org.apache.hadoop.ipc.Client.call(Client.java:1113)
at org.apache.hadoop.ipc.RPC$Invoker.invoke(RPC.java:229)
at com.sun.proxy.$Proxy1.append(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:85)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:62)
at com.sun.proxy.$Proxy1.append(Unknown Source)
at org.apache.hadoop.hdfs.DFSClient.append(DFSClient.java:933)
at org.apache.hadoop.hdfs.DFSClient.append(DFSClient.java:922)
at org.apache.hadoop.hdfs.DistributedFileSystem.append(DistributedFileSystem.java:196)
at org.apache.hadoop.fs.FileSystem.append(FileSystem.java:659)
at com.vanilla.hadoop.AppendToHdfsFile.main(AppendToHdfsFile.java:29)
What is wrong? Am I missing something?
You should try with a 2.X.X version or 0.2X version because appending a file on hdfs after hadoop 0.20.2. See more information at here and here
Append is not supported since 1.0.3. Anyway, if you really need the previous functionality, to turn on the append functionality set the flag "dfs.support.broken.append" to true.
hadoop.apache.org/docs/r1.2.1/releasenotes.html
Let's now start with configuring the file system:
public FileSystem configureFileSystem(String coreSitePath, String hdfsSitePath) {
FileSystem fileSystem = null;
try {
Configuration conf = new Configuration();
conf.setBoolean("dfs.support.append", true);
Path coreSite = new Path(coreSitePath);
Path hdfsSite = new Path(hdfsSitePath);
conf.addResource(coreSite);
conf.addResource(hdfsSite);
fileSystem = FileSystem.get(conf);
} catch (IOException ex) {
System.out.println("Error occurred while configuring FileSystem");
}
return fileSystem;
}
Make sure that the property dfs.support.append in hdfs-site.xml is set to true.
You can either set it manually by editing the hdfs-site.xml file or programmatically using:
conf.setBoolean("dfs.support.append", true);
Let's start with appending to a file in HDFS.
public String appendToFile(FileSystem fileSystem, String content, String dest) throws IOException {
Path destPath = new Path(dest);
if (!fileSystem.exists(destPath)) {
System.err.println("File doesn't exist");
return "Failure";
}
Boolean isAppendable = Boolean.valueOf(fileSystem.getConf().get("dfs.support.append"));
if(isAppendable) {
FSDataOutputStream fs_append = fileSystem.append(destPath);
PrintWriter writer = new PrintWriter(fs_append);
writer.append(content);
writer.flush();
fs_append.hflush();
writer.close();
fs_append.close();
return "Success";
}
else {
System.err.println("Please set the dfs.support.append property to true");
return "Failure";
}
}
To see whether the data has been correctly written to HDFS, let's write a method to read from HDFS and return the content as a String.
public String readFromHdfs(FileSystem fileSystem, String hdfsFilePath) {
Path hdfsPath = new Path(hdfsFilePath);
StringBuilder fileContent = new StringBuilder("");
try{
BufferedReader bfr=new BufferedReader(new InputStreamReader(fileSystem.open(hdfsPath)));
String str;
while ((str = bfr.readLine()) != null) {
fileContent.append(str+"\n");
}
}
catch (IOException ex){
System.out.println("----------Could not read from HDFS---------\n");
}
return fileContent.toString();
}
After that, we have successfully written and read the file in HDFS. It's time to close the file system.
public void closeFileSystem(FileSystem fileSystem){
try {
fileSystem.close();
}
catch (IOException ex){
System.out.println("----------Could not close the FileSystem----------");
}
}
Before executing the code, you should have Hadoop running on your system.
You just need to go to HADOOP_HOME and run following command:
./sbin/start-all.sh
For Complete Reference use https://github.com/ksimar/HDFS_AppendAPI
I want to render a previously designed BIRT report to HTML in Eclipse Indigo. I am using BIRT 4.2.1. When I do it in a normal Java application it runs fine. However, when I want to do the same from a RCP application it does not.
This is my code:
IRunAndRenderTask task=null;
IReportEngine engine=null;
EngineConfig config = null;
IReportRunnable design = null;
try{
config = new EngineConfig( );
IReportEngineFactory factory = (IReportEngineFactory) Platform.
createFactoryObject( IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY );
engine = factory.createReportEngine( config );
//use this if the report is in the bundle
Bundle bundle = org.eclipse.core.runtime.Platform.getBundle("com.accenture.workforceplanning.ui");
URL url = FileLocator.find(bundle, new Path("/reports/scenarioAnalysis.rptdesign"), null);
String rpt = FileLocator.toFileURL(url).getPath();
//Open the report design
design = engine.openReportDesign(rpt);
task = engine.createRunAndRenderTask(design);
HTMLRenderOption options = new HTMLRenderOption();
options.setImageDirectory("./");
URL url1 = FileLocator.find(bundle, new Path("/reports"), null);
String rpt1 = FileLocator.toFileURL(url1).getPath();
options.setOutputFileName(rpt1 +"/scenarioAnalysis.html");
options.setOutputFormat("html");
task.setRenderOption(options);
task.run();
task.close();
engine.destroy();
}catch( Exception ex){
ex.printStackTrace();
}
When the program reaches the task.run() I get the following error:
org.eclipse.birt.report.engine.api.UnsupportedFormatException: The output format html is not supported.
at org.eclipse.birt.report.engine.api.impl.EngineTask.setupRenderOption(EngineTask.java:2047)
at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.doRun(RunAndRenderTask.java:96)
at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.run(RunAndRenderTask.java:77)
at com.accenture.workforceplanning.ui.composites.OutputComposite.reportToHtml(OutputComposite.java:470)
at com.accenture.workforceplanning.ui.composites.OutputComposite.createReportScenarioAnalysis(OutputComposite.java:410)
at com.accenture.workforceplanning.ui.composites.OutputComposite.access$6(OutputComposite.java:308)
at com.accenture.workforceplanning.ui.composites.OutputComposite$4.widgetSelected(OutputComposite.java:214)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:240)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4165)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3754)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at com.accenture.workforceplanning.application.Application.start(Application.java:26)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
It happens the same for any type of outputformat that I want to render.
Any idea what I am doing wrong?
Thanks
Yulexi
I have managed to solve issue. Just in case somebody encounters the same problem this is what I did:
I added manually all the BIRT plug-ins to the dependencies of the product of my RCP application(For some reason, the required plug-ins were not added). Still I don't know what was the missing plug-in. But the application works fine now.
I want to increase minor document version when overriding file in ftp. When I traced the code, ContentDiskDriver2.truncateFile() works for overriding file. Inside this function I use versionService to increase version. Following code is written in truncateFile()
try {
NodeRef nodeRef = getNodeForPath(tree, DriverContent.FILE_OPEN_PARAMS.getPath());
System.out.println("Node Ref: " + nodeRef);
// Increase minor version to file.
Map<String, Serializable> versionProperties = new HashMap<String, Serializable>(2, 1.0f);
versionProperties.put(Version.PROP_DESCRIPTION, "");
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
VersionService versionService = (VersionService) applicationContext.getBean("versionService");
versionService.createVersion(nodeRef, versionProperties);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
But unfortunately I got this error.
2013-01-02 14:12:31,609 ERROR [org.alfresco.fileserver] [Sess_FTP3_192.168.1.166] Error from JLAN
org.alfresco.error.AlfrescoRuntimeException: 00020073 Transaction must be active and synchronization is required: Thread[Sess_FTP3_192.168.1.166,5,FTPSessions]
at org.alfresco.repo.transaction.AlfrescoTransactionSupport.registerSynchronizations(AlfrescoTransactionSupport.java:467)
at org.alfresco.repo.transaction.AlfrescoTransactionSupport.getSynchronization(AlfrescoTransactionSupport.java:451)
at org.alfresco.repo.transaction.AlfrescoTransactionSupport.getResource(AlfrescoTransactionSupport.java:244)
at org.alfresco.repo.transaction.TransactionalResourceHelper.incrementCount(TransactionalResourceHelper.java:71)
at org.alfresco.repo.policy.BehaviourFilterImpl.disableBehaviour(BehaviourFilterImpl.java:158)
at org.alfresco.repo.version.Version2ServiceImpl.createVersion(Version2ServiceImpl.java:212)
at org.alfresco.repo.version.Version2ServiceImpl.createVersion(Version2ServiceImpl.java:140)
at org.alfresco.filesys.repo.ContentDiskDriver2.increaseVersion(ContentDiskDriver2.java:2937)
at org.alfresco.filesys.repo.ContentDiskDriver2.truncateFile(ContentDiskDriver2.java:1652)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196)
at $Proxy97.truncateFile(Unknown Source)
at org.alfresco.filesys.repo.NonTransactionalRuleContentDiskDriver.truncateFile(NonTransactionalRuleContentDiskDriver.java:480)
at org.alfresco.filesys.repo.LegacyFileStateDriver.truncateFile(LegacyFileStateDriver.java:471)
at org.alfresco.filesys.repo.BufferedContentDiskDriver.truncateFile(BufferedContentDiskDriver.java:532)
at org.alfresco.jlan.ftp.FTPSrvSession.procStoreFile(FTPSrvSession.java:2262)
at org.alfresco.jlan.ftp.FTPSrvSession.run(FTPSrvSession.java:4924)
at java.lang.Thread.run(Thread.java:662)
Can you help me how to solve Transaction must be active and synchronization is required
I found this link..
Is the Alfresco repository document version history available via CIFS/FTP?
You've been caught by "little letter" vs "Big Letter" Alfresco services
"little letter" services are the raw services, and normally only used within other Alfresco low level services. "Big Letter" services are the wrapped user facing services, which include transactions, auditing, security etc.
For your case, you need to use the Big Letter form, so change the line
VersionService versionService = (VersionService) applicationContext.getBean("versionService");
To the correct one:
VersionService versionService = (VersionService) applicationContext.getBean("VersionService");
And you'll get a copy of the VersionService with transactions, security etc, which is what I think you need for your situation. (Note that the bean is fetched with a Big First Letter rather than little letter)
This is alternative solution I found. The use of transaction explicitly.
VersionService versionService = (VersionService) applicationContext.getBean("VersionService");
TransactionService transactionService = (TransactionService) applicationContext.getBean("transactionService");
UserTransaction tx = null;
try {
tx = transactionService.getUserTransaction();
tx.begin();
versionService.createVersion(nodeRef, versionProperties);
tx.commit();
}
catch (Exception e)
{
if(tx != null)
{
try
{
tx.rollback();
} catch (IllegalStateException e1)
{
e1.printStackTrace();
} catch (SecurityException e2)
{
e2.printStackTrace();
} catch (SystemException e3)
{
e3.printStackTrace();
}
}
}
I'm trying to do url rewriting from "beautiful" human-readable urls to webcenter internal representation and vice versa. I'm using AssetDataManager to map asset id to asset description, which I use in the URL, and the other way around. This is what I have with url assembly:
Session ses = SessionFactory.getSession();
AssetDataManager mgr = (AssetDataManager) ses
.getManager(AssetDataManager.class.getName());
List<AssetId> assets = new ArrayList<AssetId>();
assets.add(new AssetId()
{
private long id = assetId;
private String type = "Page";
#Override
public String getType()
{
return type;
}
#Override
public long getId()
{
return id;
}
});
Iterable<AssetData> assetDataItems = mgr.read(assets);
And this is for url disassembly:
Session ses = SessionFactory.getSession();
AssetDataManager mgr = (AssetDataManager) ses
.getManager(AssetDataManager.class.getName());
final String assetType = "Page";
final String subType = null;
final Condition condition = ConditionFactory.createCondition(
"description", OpTypeEnum.EQUALS, pageName);
final List<String> desiredAttributes = Arrays.asList("id");
Query query = new SimpleQuery(assetType, subType, condition,
desiredAttributes);
query.getProperties().setIsBasicSearch(true);
Iterable<AssetData> assetDataItems = mgr.read(query);
Both are used in the context of my custom assembler, which extends QueryAssembler.
Assembly works fine, reusing existing session, but disassembly fails with:
COM.FutureTense.Common.ContentServerException: ContentServerException: (Unexpected runtime exception) Error code:GENERIC SERVER ERROR
at com.openmarket.Satellite.servlet.BaseServlet.doGet(BaseServlet.java:126)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.fatwire.wem.sso.cas.filter.CASFilter.doFilter(CASFilter.java:554)
at com.fatwire.wem.sso.SSOFilter.doFilter(SSOFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
Caused by: com.openmarket.Satellite.RequestContext$RequestContextInitializationException: Co-resident Satellite Server failed to capture ICS
at com.openmarket.Satellite.RequestContext.getICS(RequestContext.java:1030)
at com.openmarket.Satellite.RequestContext.captureInputCoResident(RequestContext.java:518)
at com.openmarket.Satellite.RequestContext.<init>(RequestContext.java:428)
at com.openmarket.Satellite.servlet.BaseServlet.doGet(BaseServlet.java:112)
... 18 more
Caused by: java.lang.NullPointerException
at COM.FutureTense.Common.CS.PushVars(CS.java:217)
at com.openmarket.framework.objects.ContentCatalog.Lookup(ContentCatalog.java:305)
at com.openmarket.framework.objects.AbstractContent.Read(AbstractContent.java:510)
at com.openmarket.framework.objects.AbstractObject.Read(AbstractObject.java:460)
at com.openmarket.framework.objects.AbstractObject.Read(AbstractObject.java:446)
at com.openmarket.xcelerate.asset.AssetType.Load(AssetType.java:499)
at com.fatwire.assetapi.util.AssetUtil.isComplexAsset(AssetUtil.java:125)
at com.fatwire.assetapi.util.AssetUtil.isFlexAsset(AssetUtil.java:274)
at com.fatwire.assetapi.data.AssetDataManagerImpl.read(AssetDataManagerImpl.java:79)
at mypackage.urlassembler.ComplexDisassemblyData.getAssetIdFromPageName(ComplexDisassemblyData.java:189)
at mypackage.urlassembler.ComplexDisassemblyData.valueOf(ComplexDisassemblyData.java:145)
at mypackage.urlassembler.MyCustomURLAssembler.getDisassemblyContext(MyCustomURLAssembler.java:79)
at com.fatwire.cs.core.uri.AbstractAssembler.disassemble(AbstractAssembler.java:418)
at com.fatwire.cs.core.uri.AssemblerEngine.disassemble(AssemblerEngine.java:242)
at COM.FutureTense.Servlet.ServletRequest.disassembleURI(ServletRequest.java:852)
at COM.FutureTense.Servlet.ServletRequest.initializeParameters(ServletRequest.java:1023)
at COM.FutureTense.Servlet.ServletRequest.getParameters(ServletRequest.java:786)
at COM.FutureTense.Servlet.FRequestObj.prepInput(FRequestObj.java:1090)
at COM.FutureTense.Servlet.FRequestObj.init(FRequestObj.java:973)
at COM.FutureTense.Servlet.FRequestObj.<init>(FRequestObj.java:271)
at COM.FutureTense.Servlet.FRequestObj.newInstance(FRequestObj.java:231)
at COM.FutureTense.Servlet.FRequestObj.newInstance(FRequestObj.java:218)
at COM.FutureTense.CS.Factory.newCS(Factory.java:66)
at com.openmarket.Satellite.RequestContext.getICS(RequestContext.java:1026)
... 21 more
Which seems very strange. For some reason it is unable to use the existing session. If I change disassembly session retrieval to this, it works fine:
Session ses = SessionFactory.newSession(userName, pass);
However, I certainly would not want to create another session every time I want to resolve an url. Why do I get the exception? What would be a good way to handle this?
Ok, so apparently URL disassembly can't do anything related to DB content, as it is meant to be executed on a satellite server where it doesn't have the connectivity. For URL assembly using the DB is fine though...
So based on this, I figured out that I need to move my Asset API code to a helper class that is called from an uncached wrapper. From there it works fine.